Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу) - Страница 209
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)

Ответ
Поиск в этой теме
Непрочитано 20.07.2008, 20:12 1 |
Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)
Red Nova
 
ՃԱՐՏԱՐԱԳԵՏ, տ.գ.թ.
 
Торонто
Регистрация: 23.10.2007
Сообщений: 1,990

Со школы не ладится у меня с программированием. Все предметы щелкал, а на экзамене по информатике (Visual foxpro) программку типа суммирования столбцов списал у соседа (это уже в университете).
Не смотря на эте намерен научится писать программы для Автокада на лиспе, скачал книгу Хювенена, несколько примеров создания программ, но после получасового “смотрения” таких книг мое мышление явно притормаживает.
Решил пойти другим путем.
Нашел самый короткий лисп из моей коллекции, и прошу программистов с этого форума пошагово объяснить какой символ что означает. Надеюсь на вашу помощь.


Код:
[Выделить все]
(defun c:make-blocks-explodeable (/ adoc)
  (vl-load-com)
  (vla-startundomark
    (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
    ) ;_ end of vla-startundomark
  (vlax-for blk_def (vla-get-blocks adoc)
    (if (and (equal (vla-get-isxref blk_def) :vlax-false)
             (equal (vla-get-islayout blk_def) :vlax-false)
             ) ;_ end of and
      (vl-catch-all-apply '(lambda () (vla-put-explodable blk_def :vlax-true)))
      ) ;_ end of if
    ) ;_ end of vlax-for
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun
_____________________________________________________________________________________________________________

Прошло много лет и топик теперь представляет из себя площадку для обучения азов программирования для многих начинающих.
Так что начинающие лиспогрызы приветствуются .
__________________
Блог

Последний раз редактировалось Red Nova, 12.07.2017 в 05:43.
Просмотров: 2047979
 
Непрочитано 14.03.2022, 22:21
#4161
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


Код:
[Выделить все]
  (if (and (>= (- (cadr P_B) (cadr P_0)) 273)
		      (<= (- (cadr P_B) (cadr P_0)) 303)
		  )
	              (= L_sh 270)
   )
Примерно так, ЯТД.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 14.03.2022, 22:40
#4162
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Не, не работает. Пачиму?

----- добавлено через ~3 мин. -----
Вообще, по неправильному пути пошел, наверное, т.к. условий будет девять. Думаю, через cond надо решать.

Последний раз редактировалось Alxndr1697, 14.03.2022 в 22:46.
Alxndr1697 вне форума  
 
Непрочитано 14.03.2022, 22:48
#4163
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
если расстояние больше 273 и меньше 303
А если это условие не соблюдается? Что тогда делать?
P.S. Ползать по всей теме и разыскивать, в каком коде и в каком месте у тебя нестыковка - мне лениво и некогда.

----- добавлено через ~2 мин. -----
Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Код:
[Выделить все]
  (if (and (>= (- (cadr P_B) (cadr P_0)) 273)
		      (<= (- (cadr P_B) (cadr P_0)) 303)
		  )
	              (= L_sh 270)
   )
Примерно так, ЯТД.
Тьфу, блин, не так!
Код:
[Выделить все]
  (if (and (>= (- (cadr P_B) (cadr P_0)) 273)
		      (<= (- (cadr P_B) (cadr P_0)) 303)
		  )
	              (setq L_sh 270)
   )
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 14.03.2022, 23:58
#4164
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


Код:
[Выделить все]
 (if (< 273 (distance p_0 p_b) 303) (setq l_sh 270))
koMon вне форума  
 
Непрочитано 15.03.2022, 00:23
#4165
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,404


М-да, C#-подход уже накладывает свои ходы
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 15.03.2022, 07:00
#4166
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
А если это условие не соблюдается? Что тогда делать?
Это будет дальше следующим вопросом

Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Тьфу, блин, не так!
Оно самое! Вот, догадывался, что с дублированием setq, что-то не так.

koMon Вообще, - супер! Не знал, что < работает "на две стороны".

А как будет, если по условию, >=273 и <303?

Так?
Код:
[Выделить все]
(if (and (>= (distance P_0 P_B) 273) (< (distance P_0 P_B) 303)) (setq L_sh 270))

Последний раз редактировалось Alxndr1697, 15.03.2022 в 07:32.
Alxndr1697 вне форума  
 
Непрочитано 15.03.2022, 09:58
#4167
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


Alxndr1697,
не работает на две стороны, сравниваемых величин может быть больше трёх. последовательно проверяются пары от символа сравнения до первого nil.
я бы сделал так:
Код:
[Выделить все]
 
(setq l_sh 'out_of_range) 
(if (<= 273 (setq dist_0_b (distance p_0 p_b)) 303) 
	(if (/= 303 dist_0_p) 
			(setq l_sh 270)
	)
)

Последний раз редактировалось koMon, 15.03.2022 в 10:03.
koMon вне форума  
 
Непрочитано 15.03.2022, 11:19
#4168
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Сообщение от koMon Посмотреть сообщение
сравниваемых величин может быть больше трёх. последовательно проверяются пары от символа сравнения до первого nil.
Лучше всего делать через cond

Код:
[Выделить все]
 (setq x
  (cond
    ((a > b) 100)
    ((a <= b) 200)
    ;; Сколько угодно проверок
    (T  nil) ;; вернет NIL если ни одно условие не соблюдается
  )
)
ShaggyDoc вне форума  
 
Непрочитано 15.03.2022, 12:41
#4169
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


чем именно лучше?)
эмм и потом... тут x должен сравниваться с a и b, а не а и b между собой... еяпп
koMon вне форума  
 
Непрочитано 15.03.2022, 13:01
#4170
ShaggyDoc

Thượng Tá Quân Đội Nhân Dân Việt Nam
 
Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372


Цитата:
Сообщение от koMon Посмотреть сообщение
чем именно лучше?)
эмм и потом... тут x должен сравниваться с a и b, а не а и b между собой... еяпп
Лучше потому, что можно использовать любое количество самых разных условий. А также получать значение, если не выполняется никакое условие.

Это просто пример. cond возвращает значение, а в ее ветвях можно записать любое выражение, также возвращающее значение.
ShaggyDoc вне форума  
 
Непрочитано 15.03.2022, 13:06
#4171
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,809


для понятия нахождения числа в диапазоне из двух других чисел cond ваще не вариант имхо) потому что заменяется простым if с проверкой and на граничность, что соответствует поставленному практическому вопросу, а не теории многочисленности вариантов.
koMon вне форума  
 
Непрочитано 19.03.2022, 07:54
#4172
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Извините, что не появлялся, уведомления почему-то не приходят, вот и думал , что тут тишина.
Вопрос, как и полагал, решил через cond:

Код:
[Выделить все]
  (cond
    ((< (distance P_0 P_B) 273)
       (progn (alert (strcat "Извините, направляющих, меньше 270мм, - нет. \n"
			     "Необходимо увеличить глубину ниши для ящиков."))
          (exit))
     )
    ((and (>= (distance P_0 P_B) 273) (< (distance P_0 P_B) 303)) (setq L_sh 260));длина ящика
    ((and (>= (distance P_0 P_B) 303) (< (distance P_0 P_B) 353)) (setq L_sh 290))
    ((and (>= (distance P_0 P_B) 353) (< (distance P_0 P_B) 403)) (setq L_sh 340))
    ((and (>= (distance P_0 P_B) 403) (< (distance P_0 P_B) 453)) (setq L_sh 390))
    ((and (>= (distance P_0 P_B) 453) (< (distance P_0 P_B) 503)) (setq L_sh 440))
    ((and (>= (distance P_0 P_B) 503) (< (distance P_0 P_B) 553)) (setq L_sh 490))
    ((and (>= (distance P_0 P_B) 553) (< (distance P_0 P_B) 603)) (setq L_sh 540))
    ((and (>= (distance P_0 P_B) 603) (< (distance P_0 P_B) 653)) (setq L_sh 590))
    ((>= (distance P_0 P_B) 653) (setq L_sh 640))
   );end cond
----- добавлено через ~2 мин. -----

Что-то у меня с if не складывается)
Что тут неправильно?

Код:
[Выделить все]
  (setq P_0 (getpoint "\nУкажите левую нижнюю точку бокса <Отмена> :"))
  (setq P_L (getpoint "\nУкажите правую нижнюю точку бокса <Отмена> :"));ось x
  (if (eq (cadr P_L) (cadr P_0))
	(progn (alert (strcat "Неверная точка. Точка должна лежать в плоскости XYZ"))
	  (exit))
   )
----- добавлено через ~14 мин. -----
пс. Решено. Замена eq на /=

Последний раз редактировалось Alxndr1697, 19.03.2022 в 08:09.
Alxndr1697 вне форума  
 
Непрочитано 19.03.2022, 10:26
#4173
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


1. Зачем каждый раз вычислять (distance P_0 P_B) ? Не вижу, чтобы в данном коде переменные P_0 P_B менялись - чтобы была необходимость актуализации дистанции.
2. Здесь как раз напрашивается сделать функцию, куда передаются аргументы P_0 P_B, а возвращается длина направляющей. Либо -1, если менее 273 - а уже в вызывающей основной функции либо продолжение работы, либо alert. И так везде - где есть строго определенный законченный функционал, выносите в отдельную функцию, а в основном коде будет лишь одна строчка вызова этой функции. Читаемость кода будет гораздо лучше, и отладка проще.

Есть, конечно, определенные затраты на вызов функции и обратный возврат к выполнению основной программы. Ну потом при необходимости где-то в одиночных критичных местах развернуть вызов функции в ее код с целью повышения быстродействия - но сама то программа уже будет готова, и ею уже можно будет практически пользоваться даже с этими временными лагами первое время.
Сергей812 вне форума  
 
Непрочитано 19.03.2022, 11:32
#4174
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
1. Зачем каждый раз вычислять (distance P_0 P_B) ? Не вижу, чтобы в данном коде переменные P_0 P_B менялись - чтобы была необходимость актуализации дистанции.
2. Здесь как раз напрашивается сделать функцию, куда передаются аргументы P_0 P_B, а возвращается длина направляющей. Либо -1, если менее 273 - а уже в вызывающей основной функции либо продолжение работы, либо alert. И так везде - где есть строго определенный законченный функционал, выносите в отдельную функцию, а в основном коде будет лишь одна строчка вызова этой функции. Читаемость кода будет гораздо лучше, и отладка проще.
Да, полностью согласен и думал об этом. Но, знаний не хватает и повторюсь, делаю, как могу.
Буду признателен, если кто-нибудь напишет эту функцию ( без вла) и как ее потом вызывать, чтоб разобраться.

----- добавлено через ~5 мин. -----
Еще вопрос. Эту дистанцию можно было записать в переменную и уже, легче бы читалось. Сознательно пошел на этот шаг, чтобы уменьшить количество переменных. Это правильно, или нет?
Alxndr1697 вне форума  
 
Непрочитано 19.03.2022, 11:54
#4175
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
Сознательно пошел на этот шаг, чтобы уменьшить количество переменных. Это правильно, или нет?
неправильно. К локальным переменным самый быстрый доступ обычно, а каждый вызов функции - туда-сюда гонять данные через стек помимо самого вычисления.


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
Буду признателен, если кто-нибудь напишет эту функцию ( без вла) и как ее потом вызывать, чтоб разобраться.
Элементарно
Код:
[Выделить все]
 (defun CalcSizeDepthBox ( aP_0 aP_B / lDist lRes)
   (setq lDist (distance aP_0 aP_B))
   И тут ваш код: вместо (distance P_0 P_B) - переменная lDist, вместо setq L_sh  - setq lRes.
)
в лиспе функция возвращает последнее вычисленное или присвоенное значение, поэтому на выходе будет значение lRes - хотя в явном виде его не возвращаем, как в других языках программирования.

Ну а вызов - вызов же той же distance не вызывает затруднения, а ваша функция ничем не отличается для кода.

Последний раз редактировалось Сергей812, 19.03.2022 в 12:00.
Сергей812 вне форума  
 
Непрочитано 20.03.2022, 14:00
#4176
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Сергей812 Благодарю!
Но, немного не пойму, зачем нужна функция?
Если просто назначить переменную (setq Dist (distance P_0 P_B)) и заменить все (distance P_0 P_B) на Dist, будет неправильно?

Пока нет возможности проверить...

Последний раз редактировалось Alxndr1697, 20.03.2022 в 14:10.
Alxndr1697 вне форума  
 
Непрочитано 20.03.2022, 14:27
#4177
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
Но, немного не пойму, зачем нужна функция?
Просто есть синтаксические ошибки (выявляется на этапе компиляции), есть явные ошибки типа передачи неинициализированных переменных и т.п. (обычно выявляются во время первых прогонов runtime), и есть логические ошибки. И если программа достаточно большая, но при этом не структурирована в логические законченные функциональные узлы (функции) - то можно очень долго заниматься поиском этих логических ошибок путем пошаговой отладки. И поддержка структурированных программ проще - вносятся изменения только куда нужно, не затрагивая уже работающее.
Сергей812 вне форума  
 
Непрочитано 24.03.2022, 22:02
#4178
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Надо построить массив, один столбец, три объекта, дистанция, например 653.
Написал вот так:

Код:
[Выделить все]
(command-s "_.arrayrect" Fas_one "" "_Columns" "1" "_Rows" "3" "_Distance between rows" "653" "" "")
Не работает.
Подскажите, как надо правильно.
Alxndr1697 вне форума  
 
Непрочитано 25.03.2022, 00:21
#4179
Сергей812


 
Регистрация: 10.08.2013
Сообщений: 11,499


как минимум
Цитата:
Сообщение от Alxndr1697 Посмотреть сообщение
"_Distance between rows"
Сергей812 вне форума  
 
Непрочитано 25.03.2022, 06:02
#4180
Alxndr1697


 
Регистрация: 24.01.2008
Подольск
Сообщений: 170


Цитата:
Сообщение от Сергей812 Посмотреть сообщение
как минимум
Так это я знаю)
Делая в окне программы, я ввожу "интервал межу строками", а тут надо по другому. Как?
Есть где-нибудь справочник (не справка автокада) со всеми командами, опциями команд и их последовательностью? Не всегда все так очевидно, как делаешь через окно автокада (командную строку).
Alxndr1697 вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу)



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Вставка в таблицу поля, соотвествующего площади примитива Profan Готовые программы 272 06.06.2021 23:12
Сейсмозащита и сейсмоизоляция существующих, построенных зд. IANationalInformAgentstvo Прочее. Архитектура и строительство 216 20.01.2015 16:51
Мониторы LCD CRT Разное 94 17.06.2008 10:51
ЮМОР 2006 =) Perezz!! Разное 1122 04.01.2007 00:46