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

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

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

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

Со школы не ладится у меня с программированием. Все предметы щелкал, а на экзамене по информатике (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.
Просмотров: 1972695
 
Непрочитано 18.09.2013, 11:56
#2041
Кулик Алексей aka kpblc
Moderator

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


Например : http://www.google.ru/cse?cx=partner-...%BA&gsc.page=1
http://www.google.ru/cse?cx=partner-...sget%20dynamic
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.09.2013, 02:34
#2042
dirge


 
Регистрация: 05.09.2011
Сообщений: 38


О какой проблеме в скрипте на лиспе может идти речь если скрипт подряд отрабатывает 5-10 раз, а потом ломается? Обработка происходит в одном и том же файле, на одних и тех же объектах.
dirge вне форума  
 
Непрочитано 21.09.2013, 10:58
#2043
Кулик Алексей aka kpblc
Moderator

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


dirge, это кому адресовано и по поводу чего?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.09.2013, 11:38
#2044
dirge


 
Регистрация: 05.09.2011
Сообщений: 38


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
dirge, это кому адресовано и по поводу чего?
Это был вопрос. У меня проблема следующего характера при выборе объектов, в набор их попадает иногда меньшее количество. Происходит это рандомно, хотя координаты полигона для поиска статичны.
Есть следующий код и файл (во вложении):
Код:
[Выделить все]
 
(defun c:testing ( / I NUM OBJECTS POS POSITIONS )
       
  (setq positions (list '((3.51635e+006 2.07346e+006) (3.51739e+006 2.07202e+006) (3.51747e+006 2.07209e+006) (3.51643e+006 2.07352e+006))
	                '((3.51747e+006 2.07209e+006) (3.51914e+006 2.07023e+006) (3.51907e+006 2.07016e+006) (3.51739e+006 2.07202e+006))
	                '((3.51914e+006 2.07023e+006) (3.51962e+006 2.06969e+006) (3.51955e+006 2.06962e+006) (3.51907e+006 2.07016e+006))
	          )
  )
  
  (setq i 0)
  (while (< i (length positions))
    (if (setq num (ssget "_CP" (nth i positions)))
    	(progn
	    (setq objects
		   (vl-remove-if
		     'listp
		     (mapcar 'cadr (ssnamex num))
		   )
	    )
	    (setq pos (cons objects pos))
	)
    )
    (setq i (1+ i))
  )

  (mapcar 'length pos)
)
Результаты выдаёт следующие:
(33 91 25)
(33 91 25)
(33 91 25)
(33 91 59)
(33 25)
(14 91 59)

По ощущения кажется, что ssget зависит от времени выбора. Бред, но может кто подскажет как с этим побороться.
Вложения
Тип файла: dwg
DWG 2007
Drawing3.dwg (126.9 Кб, 2776 просмотров)
dirge вне форума  
 
Непрочитано 22.09.2013, 11:59
#2045
Кулик Алексей aka kpblc
Moderator

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


Вся область выбора должна находиться на экране.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 22.09.2013, 12:05
#2046
dirge


 
Регистрация: 05.09.2011
Сообщений: 38


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Вся область выбора должна находиться на экране.
Я думал флаг "CP" не так должен работать. Алексей спасибо, прояснили ситуацию.
dirge вне форума  
 
Непрочитано 22.09.2013, 12:11
#2047
Кулик Алексей aka kpblc
Moderator

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


CP = CrossPolygon. Вообще говоря, любой выбор, кроме "_X", "_A" и пользовательского, требует полного отображения выбираемой области.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 26.09.2013, 22:33
#2048
ashas-


 
Регистрация: 05.01.2011
Сообщений: 80


Здравствуйте Уважаемые форумчане. Вопрос не по коду, а теоретический, который не дает мне покоя уже продолжительный период времени.
При написании кода лучше использовать переменные или стараться обходится без них? И почему?
Бывает приходится использовать несколько функций в одном выражении по несколько раз в одном коде, когда можно сделать один раз и присвоить значение переменной. Но тогда переменных может стать слишком много... И если я правильно понимаю, они сидят в памяти, тем самым замедляя работу кода. Но с другой стороны не приходится снова выполнять выражение, так как оно уже храниться в переменной, что опять же должно ускорить работу кода. В общем я в растерянности и надеюсь на помощь ГУРУ этого замечательного форума...
ashas- вне форума  
 
Непрочитано 26.09.2013, 22:36
1 | #2049
Кулик Алексей aka kpblc
Moderator

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


ashas-, если честно, то тут может рассудить только эксперимент. Лично мне, например, проще работать с переменными. Дима_, например, пишет полностью лисповый код и на "лишние" переменные у него реакция сильно отрицательная
Можешь написать два (три, четыре, пять...) варианта кода и прогнать их по аналогии с http://autolisp.ru/2009/09/20/execution-speed-check/
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 27.09.2013, 07:20
1 | #2050
ShaggyDoc

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


Цитата:
Бывает приходится использовать несколько функций в одном выражении по несколько раз в одном коде, когда можно сделать один раз и присвоить значение переменной
В практических целях без переменных не обойтись. В теоретическом плане (ради доказательства религиозных убеждений) можно от переменных избавиться, но делать не такие программы, какие требуются, а такие, которые соответствуют теории. И при этом нарисовать такой код, который будет понятен только одному человеку, да и то на момент написания.

Однако переменных можно и нужно делать как можно меньше и делать их локальными, т.е. видимыми только внутри одной функции. Не следует, как в бейсике, последовательно что-то вычислять, присваивая значения. Например, не надо писать (1):
Код:
[Выделить все]
 (setq L (func params1))
(setq B (func params2))
(setq S (* L B))
Надо просто (2):
Код:
[Выделить все]
 (* (func params1) (func params1))
возможно даже не присваивая результат какой-то переменной.

Без своих функций в серьезных работах не обойтись. Из них надо формировать библиотеку, доступную в любой своей программе. Вот функции надо писать правильно, чтобы они всегда что-то полезное возвращали (даже если никаких вычислений не производится). Библиотечные функции позволяют сделать код конечных программ более простым и читаемым. Кроме того, нахождение определения функции только в одном месте позволяет легко устранять ошибки сразу во всех программах без их переделки. Как только сталкиваетесь с кодом, который повторяется хотя бы второй раз - помещайте его в библиотеку.

Но вызывать функции надо тоже с умом. Чаще всего "без ума" последовательно вызывают функцию setq, присваивая значения разным переменным (см. пример 1). Если предположить, что без переменных ну никак не обойтись, то надо было писать (3):
Код:
[Выделить все]
 (setq L (func params1) 
                           B   (func params2)
                   )
т.е. выполняя функцию setq один раз.
Цитата:
они сидят в памяти, тем самым замедляя работу кода
Переменные работу не замедляют, они занимают память. А вот вызовы функций могут замедлить работу, т.к. при каждом вызове интерпретатор должен проверить наличие такой функции и правильность её применения. Код (3) будет работать быстрее кода (1)
ShaggyDoc вне форума  
 
Непрочитано 27.09.2013, 14:04
1 | #2051
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Тут сначала надо определиться что такое переменная - переменная по замыслу своему это индексированная ячейка памяти которая МЕНЯЕТ свое значение в ходе выполнения программы. А сейчас я скажу то, что наверное не все воспримут - но перед тем как это опровергать, попробуйте осмыслить. В автолиспе переменных в вышеуказанном смысле НЕТ. Да да их просто нет и соответственно Вы не можете их использовать, даже если Вам кажется что Вы так делаете. В автолиспе можно переопределять именна, причем абсолютно не важно используеться аналогичное имя уже или нет. Поясню код (setq a 5 a 10 a 20) создает три значения 10 20 и 30, но т.к. все они индексируются через имя "a", то по окончании функции доступно для программы остается только последнее. Все недоступные значения будут уничтожены при очередном ручном, либо автоматическом, вызове "сборщика мусора". Но т.к. классическая школа программирования объясняет нам все через "ячейки", в автолиспе реализован механизм который внешне очень похож на императивную парадигму. Все согласны?? Я при этом полностью согласен далее называть их переменными, чтоб никого не путать.
Вопрос ведь в использовании этого механизма, а не в устройстве автолиспа, но к сожалению т.к. мы сейчас говорим о конкретном языке, то для понимания "правильности" использования переменных, без его устройства нам не обойтись (ведь глупо говорить в общем о необходимости переменных т.к. - в си без них, ну просто никак, а в хаскеле их просто нет как таковых). Итак у нас есть механизм использования переменных, вопрос - стоит ли им пользоваться. Мой ответ (а я пока, вроде как, неформально считаюсь здесь ведущим "идеологом" в этой области) - да без них невозможно обойтись в автолиспе. Есть варианты когда хоть убейся нужны глобальные переменные, есть функции автолиспа которые заточенны под их использование. Есть ActiveX который содержит в себе изменяемые объекты (вот их свойства, кстати, мы с полной правотой можем называть как "настоящие" переменные - то есть мы можем изменять свойства конкретных объектов). Это необходимость сделанна по нескольким причинам - во первых для "простого инженера" будет несколько сложней написать "вспомогалку" на 3 строчки (с императивной парадигмой он наверное знаком с большей вероятностью); во вторых полноценно реализовывать в интерпритаторе монады и замыкания (механизмы в языках функционального программирования позволяющие полностью не использовать изменяемые значения) это не простое занятие; в третьих использование COM все равно выходит за рамки функциональной парадигмы (т.к. объекты содержат изменямые значения, а реализовывать их через монадические представление это такой-же бред как и использование 1001 переменной в лиспе) и соответственно вся чистота (это термин описывающий тип функций, а не мое отношение к ним) всей "лестницы" функций использующий COM накрывается медным тазом. Весь вопрос в удобстве, либо не удобстве их использования.
Я убежден, что 95% примеров использования здесь переменных вызванны недостаточной степенью владения функционалом автолиспа. Большинство начинающих считают что lambda это такое приложение к mapcar'у, но вопрос опять-таки не про них - считаем что мы разбераем случай не для вышеупомянутого "простого инжинера" (не чуть не хочу задеть профессию - имеется в виду человек который, что-то дописывает себе к автокаду постольку поскольку) - ему тратить время на "изыски" некогда, да и наверное не зачем,а для того перед кем стоит реальная практическая Offtop: ShaggyDoc задача по написанию программы на автолиспе. Используемые внутри программы имена мы можем определять и использовать по разному. Можем глобально setq'овать, можем локализировать используемые внутри функции и сразу со старта их "инициализировать" через setq, можем использовать lambda функционал. Ну про глобальные тут все понятно и вроде все согласны - внутренние имена подлежат обязательной локализации. Вопрос 2 - как лучше сделать - локализовать имена и присвоить им значения, либо использовать лямбды - по мне разницы особой нет - в данном случае вопрос действительно предпочтений. При локализации имен есть плюс в случае если нужно дать имена вычисляемым друг из друга значениям (в автолиспе нет функционала рекурсирвного определения типа letrec), что можно сделать без проблем с помощью setq (когда определяеться первая "пара" она сразу доступна второй), но при лямбдах, вне зависимости от размера используемой основной функции, нам не нужно "городить" имена типа my-first-value т.к. - как всегда можно автоматически провести расстановку отступов и сразу будет видно где кто - никогда не перепутаешь и можно в ручную задать нужную область ее видимости. Совсем другое дело это использованием переменных с именно изменяемым значением в течении работы программы (не 1 раз как в случае "инициализации" локально объявленных - а как-бы циклично).
Offtop: Сократ мне друг, но истинна дороже
Вот здесь хочеться начать с новой строчки. Насчет указанных ShaggyDoc'ом практических целей и пр. Есть в автолиспе несколько "императивно-ориентированных" функций в которых не использование переменных похоже на бред сумашедшего например:
Код:
[Выделить все]
 (defun coll->list(obj / ret)
  (vlax-for x obj (setq ret (cons x ret)))
  (reverse ret))
В чистом виде императивная функция которая постоянно циклично изменяет определение ret, в основе которой лежит как раз-таки "императивно-ориентированный" vlax-for. Писать подобное через "функциональный функционал" в автолиспе - бред. Аналог кода будет в 15 раз длиннее и гораздо сложнее алгоритмически. Но, я уверен, что ShaggyDoc имеет в виду не только этот случай и вот здесь я с ним имею радикально противоположную точку зрения. Принимая "простоту" использования переменных мы сталкиваемся с целым букетом гораздо более сложных проблем в корне которых лежит, то, что мы не знаем (в момент анализа программы), что у нас находиться под конктретным именем. Как только Вы начнинаете "крутить" переменными весь функциональный подход летит в мусорное ведро. У вас теряеться и структура и читабельность прграмм - здравствуй VLIDE и соотношение времени написание:отладка 1:10, досвидания рекурсия (если использовать "наружные" переменные рекурсивно - это гарантированный "провал") вся суть использования лиспа теряеться - пишите тогда на VB - для чего тогда все эти скобки? - ради пары фишек типо mapcar'a? Что программы становяться не читаемыми - покажите мне такую, правильно написаннаю - я за 5 секунд отформатирую ее и логика сразу "всплывет", а вот как раз при использовании переменных наступает полная "каша" в которой без пошаговой отладки никто ничего не поймет. Программы, написанные в лисп ключе -это по сути своей метод представления алгоритма - если Вы посмотрите на интегральную формулу - Вы тоже скажите что это чушь - т.к. многие ее не понимают, но почему-то для описания математики используют именно их, а не описывают все простыми понятными словами - т.к. многие вещи ими просто умрешь выводить. А "чехорда" из переменных не несет в себе никакой логики - ее невозможно понять не выполнив ее пошагово (в уме - что на практике просто нереально, либо отладчиком). Хочу особо подчеркнуть, что только при отказе от таких переменных лисп программа имеет декларативный вид - с ними это чистой воды императивка просто написанная лисп синтаксисом.
Скорость выполнения, в большинстве случаев, упадет при использовании функционального подхода (при прочих равных), но программы станут не читаемыми, и не редактируемые. Лично мне глубоко плевать на эти 3% времени - они не будут заметны ни при каком случае, а вот при попытке разложить хоть каплю сложный алгоритм "на переменные" - сразу идет тенденция к его упрощению (т.к. сложные вещи описать ими ой как непросто) и в результате мы видим выполнение быстрых переменных логарифмически неэффективно - и как вывод - эти 3% - надуманная чушь.
Есть в автолиспе еще отсутствие хвостовой рекурсии - это грустный факт. Из за которго мне несколько раз приходилось переводить готовую программу в "переменное" исполнение. Но я всегда обязательно оставлял "оригинал" - т.к. если потрбуется расширить функционал - гораздо проще добавить его в нем, чем пытаться копашиться в переменных (такая вот ручная оптимизация).
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 27.09.2013 в 15:18.
Дима_ вне форума  
 
Непрочитано 01.10.2013, 21:58
#2052
ashas-


 
Регистрация: 05.01.2011
Сообщений: 80


Кулик Алексей aka kpblc, ShaggyDoc, Дима_, благодарю за подробные разъяснения.
Не все понял из того что написал Дима_, но в целом суть уловил. И буквально недавно я стал уходить от переменных (раньше без них совсем не мог), поэтому и возник такой вопрос . Действительно я обратил внимание, что без переменных код читается легче, как писал Дима_ хоть и получается длиннее. И стараюсь как можно меньше работать с автокадом (командами и объектами, тягая из них информацию), понял что лучше сохранить информацию в лиспе, чем несколько раз ее вытаскивать из объекта. В общем еще раз спасибо, это было познавательно.
ashas- вне форума  
 
Непрочитано 12.10.2013, 20:36
#2053
Ilez

Техник АС, КЖ
 
Регистрация: 24.09.2013
Ingushetiya
Сообщений: 392


Здравствуйте уважаемые участники. Такой вопрос. Возможно ли изучать AutoLisp и пользоваться им, не имея никаких знаний английского языка?
Почему спрашиваю. Один знакомый поступив на специальность программирования, начал изучать английский, так как он входил в программу обучения и ему в деканате сказали, что при обучении на этой специальности он должен по-любому изучать английский. Но это целая специальность, где изучаются много языков и на глубоком уровне. А для AutoLispа требуется ли хоть базовое знание? Знания английского практически нулевые. Заранее спасибо за ответ.
Ilez вне форума  
 
Непрочитано 12.10.2013, 20:41
1 | #2054
Кулик Алексей aka kpblc
Moderator

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


Документация для AutoLISP доступна только на английском языке. Ну или искать книги Полещука Н.Н.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 12.10.2013, 21:01
1 | #2055
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


английский разговорный + технический в обязательном порядке, без этого далеко не пойдешь
gomer вне форума  
 
Непрочитано 14.10.2013, 09:05
1 | #2056
alex8888

Инженер
 
Регистрация: 27.04.2009
Deutschland
Сообщений: 208


Вот как раз английский разговорный и не обязательно. Достаточно только сотни слов, обычных в программировании типа save, open, edit ...

Или? Ну ежели только для самоуспокоения.
alex8888 вне форума  
 
Непрочитано 14.10.2013, 10:41
#2057
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от alex8888 Посмотреть сообщение
Вот как раз английский разговорный и не обязательно
это называется вариться в собственном соку...
gomer вне форума  
 
Непрочитано 18.10.2013, 16:59
#2058
Vladimir_Sergeevich

рисую дороги, в перерывах курю Lisp
 
Регистрация: 20.04.2011
Пермь
Сообщений: 475
<phrase 1= Отправить сообщение для Vladimir_Sergeevich с помощью Skype™


Есть задачка. Найти пересечение двух линий и по полученой координате выбрать ближайший к этой точке примитив. Точку я нашел, а как привязаться к объекту? _select !pt не катит, потому как ловит только тогда, когда картинка достаточно далеко.
Зачем мне это нужно: есть номограмма, по значениям двух параметров надо выбрать изолинию на пересечении (но точка может оказаться не на изолинии, а рядом...)
Поиском ничего вразумиельно не нашел.
__________________
Не труд сделал из обезьяны человека, а лень и жажда халявы...
Vladimir_Sergeevich вне форума  
 
Непрочитано 18.10.2013, 19:19
#2059
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


http://forum.dwg.ru/showpost.php?p=1044227&postcount=11
gomer вне форума  
 
Непрочитано 18.10.2013, 20:56
#2060
Vladimir_Sergeevich

рисую дороги, в перерывах курю Lisp
 
Регистрация: 20.04.2011
Пермь
Сообщений: 475
<phrase 1= Отправить сообщение для Vladimir_Sergeevich с помощью Skype™


То ли я дурак... попобовал - в набор загремели все изолинии ниже искомой с ей во главе. В чем косяк такого выбора, пока не понимаю.

З.ы. но за идею спасибо. В итоге ssget _с, постепенно увеличиваю размер рамки, пока хоть кто туда не попадет. (Пишу с телефона, поэтому приложить не могу).

З.з.ы 2 Ilez. Английский нужно знать как минимум в части, касающейся автокада. Почти все свойства объектов и сам объекты, да и методы написаны простым английским языком... зная язык легче запомнить что есть что и соответственно применить, где надо.
__________________
Не труд сделал из обезьяны человека, а лень и жажда халявы...

Последний раз редактировалось Vladimir_Sergeevich, 18.10.2013 в 22:56.
Vladimir_Sergeevich вне форума  
Ответ
Вернуться   Форум 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