| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Программеры, где моя ошибочка?

Программеры, где моя ошибочка?

Ответ
Поиск в этой теме
Непрочитано 27.02.2004, 15:12 #1
Программеры, где моя ошибочка?
{Smirnoff}
 
Инженер по системам безопасности
 
Рига
Регистрация: 23.11.2003
Сообщений: 1,099

Прошу прощения, посмотрите пожалуйста код. Уже час с лишним немогу найти мерзкую ошибочку. Иногда, спотыкаешься на какой то ерунде...

Короче, функция вносит изменения в X-записи соответствующего словаря. Все данные передаються через аргументы. Проверку на совместимость данных описанную в заголовке я убрал, чтобы небыло большого листинга:
Код:
[Выделить все]
;;;******************************************************************************************
;;;                                                                                         *
;;;                     *** ФУНКЦИЯ ЗАПИСИ ДАННЫХ В Х-ЗАПИСИ СЛОВАРЯ ***                    *
;;;                                                                                         *
;;;Функция записывает данные в нужную Х-запись содержащуюся в соответствующем словаре и     *
;;;осуществляет проверку данных на совместимость формата данных с форматом соответствующей  *
;;;точечной пары.                                                                           *
;;;                                                                                         *
;;;******************************************************************************************

(defun SC_Settings_XRecord_Write (
				  
;;;				  АРГУМЕНТЫ:
				  wantedDict 	;- словарь содержащий нужную X-запись
				  wantedXRec 	;- нужная X-запись
				  writeDXF   	;- код DXF группы куда будет производиться запись
				  writeData  	;- данные записываемые в соответствующую группу
				  /
;;;				  ПЕРЕМЕННЫЕ:
				  curDataList 	;- список данных Х-записи
				  )
  (setq curDataList (dictsearch wantedDict wantedXRec))
  (if(= nil (assoc writeDXF curDataList))
    (setq curDataList (append curDataList (list(cons writeDXF writeData)))); если группы нет- создать
    (setq curDataList (subst(cons writeDXF writeData)(assoc writeDXF curDataList) curDataList)); если есть- заменить данные
    ); end of if
    (entmod curDataList)
    (princ)
    ); end of SC_Settings_XRecord_Write

;;;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Почему то не работает условие (if(= nil (assoc writeDXF curDataList)). Она постоянно делает (setq curDataList (append curDataList (list(cons writeDXF writeData)))) тем самым дописывая точечные пары с дублирующимися DXF кодами, а мне нужно надписывать значение если пара с таким кодом уже существует. Может я дурак, но не могу понять в чем дело! Заблудился в трех соснах... [sm1708]
Просмотров: 7797
 
Непрочитано 27.02.2004, 16:32
#2
kos

LISP-программист
 
Регистрация: 25.08.2003
Тутэйшы
Сообщений: 238


Вроде все должно работать. Посмотри значения переменных writeDXF и curDataList, может они формируются неправильно. И еще, зачем усложнять код? Я бы сделал так:
Код:
[Выделить все]
(if (assoc writeDXF curDataList)
; если есть- заменить данные 
  (setq curDataList (subst (cons writeDXF writeData)
                           (assoc writeDXF curDataList) curDataList))
; если группы нет- создать 
  (setq curDataList (append curDataList 
                            (list(cons writeDXF writeData))))
); end of if
Надеюсь при копировании скобок не потерял...
__________________
Там все есть для счастья - меня там только нет.
Так это значит, что я там - буду!
kos вне форума  
 
Автор темы   Непрочитано 27.02.2004, 17:50
#3
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Код укоротил, спасибо...
Но! Хоть убейся:
Код:
[Выделить все]
((-1 . <Entity name: 40082d60>) (0 . "XRECORD") (5 . "2C") (102 . 
"{ACAD_REACTORS") (330 . <Entity name: 40082d58>) (102 . "}") (330 . <Entity 
name: 40082d58>) (100 . "AcDbXrecord") (280 . 1) (140 . 3.0) (140 . 194.0) (140 
. 88.0) (140 . 194.0))
Это результат запуска функции с аргументами writeDXF 140 и различными значениями writeData. Почему то дописывает, а не меняет непойму...

Если сделать переменную curDataList глобальной и вручную сэмитировать условие (assoc 140 curDataList), совершенно верно выдает (140 . 3.0), но не как ни NIL!!! А в проге выполняет как будто там NIL. Код укоротил, спасибо...

Уже два повода выпить водки. Пятница и эта функция... [sm700]
{Smirnoff} вне форума  
 
Непрочитано 27.02.2004, 20:02
#4
BigBrother

Design & programming :)
 
Регистрация: 14.02.2004
Новосибирск
Сообщений: 172
<phrase 1= Отправить сообщение для BigBrother с помощью Skype™


А вставить breakpoint и сделать inspect нужного выражения религия не позволяет?
Еще, subst заменит только 1 вхождение.
А если их несколько?

Еще примечание по стилю: но это уже сугубое IMXO...
Функция в отличие от команды должна (как правило) возвращать аргумент. Который потом обрабатывается.

Код:
[Выделить все]
(defun SC_Settings_XRecord_Write (writeDXF writeData / curDataList)
  (setq	curDataList
	 '((0 . "XRECORD")(5 . "2C")(102 . "{ACAD_REACTORS")(102 . "}")(100 . "AcDbXrecord")(280 . 1)(140 . 3.0)
	  ))
  (if (assoc writeDXF curDataList)
    (setq curDataList
	   (subst (cons writeDXF writeData)
		  (assoc writeDXF curDataList)
		  curDataList
	   )
    )
    (setq curDataList
	   (append curDataList
		   (list (cons writeDXF writeData))
	   )
    )
  )
)
Вызов (SC_SETTINGS_XRECORD_WRITE 140 1) возвращает
((0 . "XRECORD") (5 . "2C") (102 . "{ACAD_REACTORS") (102 . "}") (100 . "AcDbXrecord") (280 . 1) (140 . 1))

Так что вроде все нормально.
BigBrother вне форума  
 
Непрочитано 27.02.2004, 21:39
#5
leha

ACAD, UG, CATIA - программирование
 
Регистрация: 17.09.2003
Таганрог
Сообщений: 9


С некоторыми словарями бывают глюки. Не факт, что поможет, но попробуй вместо

(entmod curDataList)

написать

(dictremove wantedDict wantedXRec)
(entmakex curDataList)
leha вне форума  
 
Автор темы   Непрочитано 28.02.2004, 12:52
#6
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


>leha
И в самом деле это оказался "глюк" функции ENTMOD по отношению к X-Записи содержащейся в словаре. Если в списке точечных пар, изменить одну пару и "надписать" её ENTMOD, то значение возвращаемое этой функцией будет абсолютно нормальным. Однако если считать после этого саму Х-Запись то окажеться, что точечная пара которая должна была быть "надписана" осталась на месте, а новая пара с таким же DXF кодом добавилась.

Ваш способ с "уничтожением" работает. Спасибо!
Код:
[Выделить все]
  (dictremove wantedDict wantedXRec) 
  (dictadd wantedDict wantedXRec (entmakex curDataList))
>BigBrother
Вы неполностью сэмитировали мою ситуацию. Во первых "эффект" возникает только в Х-Записи которая уже содержится в словаре, во вторых он возникает только при "надписывании" с помощью ENTMODE.
Насчет религии, вы отчасти правы. Мне просто "в лом" пользаваться отладчиком, потому что большинство ошибок как то сразу находятся. Одно время я пытался себя к этому приучить, однако больше путался и тратил много времени. Наверное на определенном этапе всетаки придется себя приучить, функции становятся все сложнее. А на некорректность AutoLISP "нарвался" в первый раз, я всего около года программирую. Т. к. этот глюк эммитировал неправильное выполнение моего условия, это меня зациклило. Насчет вхождений, оно и должно быть одно. Суть этой функции в том что она вызывается из различных программ входящих в одно приложение и сохраняет в чертеже некоторые установки для использования в следующем сеансе редактирования. Возвращаемый аргумент не используется.
{Smirnoff} вне форума  
 
Непрочитано 28.02.2004, 23:35
#7
leha

ACAD, UG, CATIA - программирование
 
Регистрация: 17.09.2003
Таганрог
Сообщений: 9


> Fantomas
Если не секрет, что за словарь? Т.е. это какой-то из стандартных ACAD-овских словарей или свой собственный?
До сих с подобным глюком сталкивался только на словаре "DWGPROPS" (там после entmod вообще повторяется весь список словаря), а для всех своих словарей entmod вроде работает нормально. В общем, есть подозрение, что этот глюк только для стандартных ACAD-овских словарей (да и то далеко не для всех).
leha вне форума  
 
Автор темы   Непрочитано 29.02.2004, 00:46
#8
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Собственный, пользовательский словарь. С ситуацией "дублирования" всех точеных пар тоже столкнулся.

Далее извините за лирику...

Проверял я эту функцию после того как три дня подряд чертил "халтуру" до 3 часов ночи, на трезвый анализ уже сил не хватало. Поэтому я тупо "набил" две функции ЗАПИСЬ и ПРОВЕРКА РЕАЛЬНОЙ Х-ЗАПИСИ, чтобы посмотреть что в самом деле происходит. Так вот, переодически (систему я не уловил) точечных пар вдруг становилось в два раза больше, менялся и их порядок (это кроме вышеописанного "дописывания"). Именно это заставило меня провести эту операцию раз 20 в перемешку с анализом своего кода (что там анализировать то в трех строчках). Хотелось бы конечно докапаться до истины. Но пока остановился на том что надо полностью "убивать" и восстанавливать Х-Запись по вашему способу.

Вот код создания словаря:
Код:
[Выделить все]
(defun SC_Settings_Dict_Create (/ XRecord1)
   (if(= nil(dictsearch(namedobjdict) "MyDict"))      (progn
	(setq sc:Dictionary (entmakex '((0 . "DICTIONARY")(100 . "AcDbDictionary"))))
    	(dictadd (namedobjdict) "MyDict" sc:Dictionary)
	(setq XRecord1 (entmakex '((0 . "XRECORD")(100 . "AcDbXrecord"))))
	(dictadd sc:Dictionary "Settings #1" XRecord1)
	); end of progn
      ); end of if
	      (princ)
	       ); end of SC_Settings_Dict_Create
Может тут что не так? Мы с вами беседовали на autocad как это сделать через ActiveX, я сделал, но по "обычному" действительно проще.

Мне еще кстати надо некоторые установки сохранять не в чертеже. Что посоветуете? Купить большую книжку "Реестр Windows 2000/XP" (слабо пока соображаю в организации регистра) или в собственном файле в виде ассоциированных списков в виде строк или собственного формата с разделителями? В программировании я пока чайник (прогрессирующий)...
{Smirnoff} вне форума  
 
Непрочитано 29.02.2004, 13:49
#9
BigBrother

Design & programming :)
 
Регистрация: 14.02.2004
Новосибирск
Сообщений: 172
<phrase 1= Отправить сообщение для BigBrother с помощью Skype™


Цитата:
Сообщение от Fantomas
Мне еще кстати надо некоторые установки сохранять не в чертеже. Что посоветуете? Купить большую книжку "Реестр Windows 2000/XP" (слабо пока соображаю в организации регистра) или в собственном файле в виде ассоциированных списков в виде строк или собственного формата с разделителями? В программировании я пока чайник (прогрессирующий)...
В DOSLIB есть функции работы с ini файлами.
Единственный головняк, что придется преобразовывать строки в числа.
В файле в виде ассоциированных списков удобнее на мой взгляд.
Считываем строку, применяем read и работаем со списком.
BigBrother вне форума  
 
Автор темы   Непрочитано 29.02.2004, 17:30
#10
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Мне вот тоже собственный файл с ассоциированными списками больше по душе. Это один мой знакомый программер на Паскале, говорит мне что, надо делать профессионально и писать все в регистр (тем более что функции для этого есть), но Паскаль есть Паскаль.

С традиционными INI файлами связываться не хочеться, они и делаються в общем то для того чтобы представить информацию в установках в более мениее читабельном виде, чтобы программер или продвинутый пользователь мог поправить этот файл "руками". Для меня это пока не требуется.

Наверное не буду морочить себе голову и сделаю собственный файл с ассоциированными списками.
{Smirnoff} вне форума  
 
Непрочитано 29.02.2004, 22:52
#11
leha

ACAD, UG, CATIA - программирование
 
Регистрация: 17.09.2003
Таганрог
Сообщений: 9


> Fantomas
По поводу словарей:
Спасибо за ответ. А я думал, что проблема в том, что к стандартным словарям может быть привязано какое-то событие (реактор), и вот оно это бяку и делает. Но похоже, что это общий глюк словарей, и надежней будет для всех словарей действовать по схеме: удалил->создал

По поводу второго:
Тут, как говорится, на вкус и цвет товарищей нет. Надо выбирать то, что удобно в данном конкретном случае. Если настройки будут считываться только из LISP, то строка с ассоциативным списком, наверное, будет самой удобной. А по поводу того, где хранить эту строку - это тоже надо выбирать в зависимости от случая. Можно, при желании, и в реестре. Функции чтения/записи в реестр есть и VLISP:
vl-registry-delete, vl-registry-descendents, vl-registry-read, vl-registry-write. Можешь почитать тему http://www.autocad.ru/cgi-bin/f1/board.cgi?t=7002Ju - там обсуждалось, где и как лучше хранить настройки.
Кто-то считает, что хранить в реестре профессиональнее, кто-то считает, что в реестре и так полно всякого хлама, чтобы туда писать еще и что-то свое.

Дальше все ИМХО:
Я предпочитаю хранить на диске в текстовых файлах. Формат уже действительно не принципиален, а место надо определять для каждого пользователя отдельно. Небольшая функция для определения одной из "специальных папок" Windows:

(defun get_special_folder (folder / WScript_obj answer)
; folder может быть:
; "AllUsersDesktop" - Windows 2000
; "AllUsersStartMenu" - Windows 2000
; "AllUsersPrograms" - Windows 2000
; "AllUsersStartup" - Windows 2000
; "Desktop" - Windows 98/ME, Windows 2000
; "Favorites" - Windows 98/ME, Windows 2000
; "Fonts" - Windows 98/ME, Windows 2000
; "MyDocuments" - Windows 98/ME, Windows 2000
; "NetHood" - Windows 98/ME, Windows 2000
; "PrintHood" - Windows 98/ME, Windows 2000
; "Programs" - Windows 98/ME, Windows 2000
; "Recent" - Windows 98/ME, Windows 2000
; "SendTo" - Windows 98/ME, Windows 2000
; "StartMenu" - Windows 98/ME, Windows 2000
; "Startup" - Windows 2000
; "Templates" - Windows 2000
; Возвращает или путь, или nil
(vl-load-com)
(if (setq WScript_obj (vlax-get-or-create-object "WScript.Shell"))
(if (/= (setq answer
(vlax-invoke-method (vlax-get-property WScript_obj "SpecialFolders") "Item" folder))
"");/=
answer
);if
);if
);defun

Но надо учитывать ситуации, что пользователь может изменить файл ручками, и в том числе и написать туда вообще что-то нечитабельное.

Есть еще вариант, но это только теоретически, т.к. читал, что это возможно, но сам пока не пробовал, сейчас только пытаюсь разобраться. Если настроек очень много, и надо запретить пользователю возможность их как-то изменять. Хранить их так же на диске, но в запароленном файле *.mdb (база данных). А считывать, изменять их через ADO (ActiveX Data Objects). Говорят, что сломать пароль в таком файле очень сложно (можно или просто запортить файл, или его удалить), а доступ к данным очень быстрый.
leha вне форума  
 
Автор темы   Непрочитано 01.03.2004, 11:08
#12
{Smirnoff}

Инженер по системам безопасности
 
Регистрация: 23.11.2003
Рига
Сообщений: 1,099


Да наверное пока остановлюсь на своем файле со списками.

Хотел заметить только насчет пароля к *.mdb.

Эксплуатирую я тут одну "глючную" немецкую софту. Эти немецкие кретины наделали в своей софте столько "багов" что она постоянно глючила. И вот однажды полетела база данных в формате *.mdb которая лежала на сервере и к которой обращались программы-клиенты. Короче ситуация очень плохая. Repair сделать немогу, тем более открыть таблицы в Access - база запоролена. Вспоминаю что один мой знакомый сисадмин хвастался что может в 15 минут сломать любой пароль к MDBшной базе. Переписываю ее на CD-R и бегом к нему. Через 10 минут действительно получаю 6-ти значный пароль случайного вида типа 5Jas8Y. Теперь слыша о запороленных MS Access, я тихо улыбаюсь. Когда очередной раз приехал немец, разбираться со своим "глюкаловом", сделал большие глаза. Правда, выслушав мою эмоциональную речь, про то что я думаю об их программе оставил пароль от базы и в новой версии.
{Smirnoff} вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Программеры, где моя ошибочка?

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск