Имя: Пароль:
1C
1С v8
Как можно уменьшить код, в котором сравниваем 2 массива?
,
0 Karamello
 
02.11.22
10:47
РазделениеПервойВерсии = СтрРазделить(ПерваяВерсия,".");
    РазделениеВторойВерсии = СтрРазделить(ВтораяВерсия,".");
    
    Редакция = Новый Массив;
    
    Для Индекс = 0 По 3 Цикл
        Если РазделениеПервойВерсии[0] > РазделениеВторойВерсии[0] Тогда
            Редакция = РазделениеПервойВерсии;
            Продолжить;
        ИначеЕсли
            РазделениеПервойВерсии[0] < РазделениеВторойВерсии[0] Тогда
            Редакция = РазделениеВторойВерсии;
            Продолжить;
        Иначе
            Если РазделениеПервойВерсии[1] > РазделениеВторойВерсии[1] Тогда
                Редакция = РазделениеПервойВерсии;
                Продолжить;
            ИначеЕсли
                РазделениеПервойВерсии[1] < РазделениеВторойВерсии[1] Тогда
                Редакция = РазделениеВторойВерсии;
                Продолжить;
            Иначе
                Если РазделениеПервойВерсии[2] > РазделениеВторойВерсии[2] Тогда
                    Редакция = РазделениеПервойВерсии;
                    Продолжить;
                ИначеЕсли
                    РазделениеПервойВерсии[2] < РазделениеВторойВерсии[2] Тогда
                    Редакция = РазделениеВторойВерсии;
                    Продолжить;
                Иначе
                    Если РазделениеПервойВерсии[3] > РазделениеВторойВерсии[3] Тогда
                        Редакция = РазделениеПервойВерсии;
                        Продолжить;
                    ИначеЕсли
                        РазделениеПервойВерсии[3] < РазделениеВторойВерсии[3] Тогда
                        Редакция = РазделениеВторойВерсии;
                        Продолжить;
                    Иначе
                        Сообщение = Новый СообщениеПользователю;
                        Сообщение.Текст = "Версии программ равны!";
                        Сообщение.Сообщить();
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4",Число(Редакция[0]), Число(Редакция[1]), Число(Редакция[2]), Число(Редакция[3]));
    Сообщение.Сообщить();
1 Lama12
 
02.11.22
10:49
(0) Что считать равными массивами?
2 Кирпич
 
02.11.22
10:49
Если ПерваяВерсия = ВтораяВерсия Тогда
                        Сообщение = Новый СообщениеПользователю;
                        Сообщение.Текст = "Версии программ равны!";
                        Сообщение.Сообщить();
КонецЕсли;
3 Lama12
 
02.11.22
10:51
Очень похоже на тестовую задачку в Эльдорадо.
4 Smallrat
 
02.11.22
10:52
все не читал
ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СтрокаВерсии1, СтрокаВерсии2)
5 mistеr
 
02.11.22
10:54
(0) Заменить вложенные Если на цикл.
6 Мимохожий Однако
 
02.11.22
10:54
При сравнении каждого элемента неплохо преобразовать значение массива к числу и потом сравнивать.
На питоне это в одну строку
  s1 = list(map(int, k1.split('_')))
7 b_ru
 
02.11.22
10:55
Цикл то у тебя не используется. Надо было что-то вроде:

   Для Индекс = 0 По 3 Цикл
        Если РазделениеПервойВерсии[Индекс] > РазделениеВторойВерсии[Индекс] Тогда
            Редакция = РазделениеПервойВерсии;
            Прервать;
        ИначеЕсли
            РазделениеПервойВерсии[Индекс] < РазделениеВторойВерсии[Индекс] Тогда
            Редакция = РазделениеВторойВерсии;
            Прервать;
        КонецЕсли;
   КонецЦикл;  
8 Kassern
 
02.11.22
10:56
(6) Примерно так и делает (4)
9 ass1c
 
02.11.22
11:06
Как минимум условия  РазделениеПервойВерсии[0] > РазделениеВторойВерсии[0] и РазделениеПервойВерсии[0] < РазделениеВторойВерсии[0] и т.д. можно сократить до

СравнениеЗначений = Новый СравнениеЗначений();
Результат = СравнениеЗначений.Сравнить(РазделениеПервойВерсии[0],РазделениеВторойВерсии[0]);

должно выглядеть более читабельным
10 Мимохожий Однако
 
02.11.22
11:25
(9) Если есть функция в БСП, то незачем изобретать лисапед. В (4) что не устраивает?
11 mistеr
 
02.11.22
11:27
(10) Это тестовое задание на знание БСП
12 ass1c
 
02.11.22
11:47
(10) Как можно уменьшить код, в котором сравниваем 2 массива? - один из вариантов уменьшение кода. Безумно рад за пункт (4), просто в восторге
13 MyNick
 
02.11.22
11:53
(0) ОМГ.
шо это?
14 Мимохожий Однако
 
02.11.22
12:21
(11) Тестовое задание для Волшебного форума )
15 Karamello
 
02.11.22
12:51
(9) Спасибо, получилось гораздо опрятней)
16 okmail
 
02.11.22
14:26
Если Массив1.Количество() <> Массив2.Количество() Тогда
        Возврат Ложь;
    КонецЕсли;
    
    Для Каждого Элемент Из Массив1 Цикл
        Если Массив2.Найти(Элемент) = Неопределено Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Истина;
17 lodger
 
02.11.22
14:37
(15) в твоём коде лишняя строка вида "Для Индекс = 0 По 3 Цикл". уже выкинул?
18 Бычье сердце
 
02.11.22
14:38
(0)
ВерсииРавны = ПерваяВерсия = ВтораяВерсия;

Так не прокатит?
19 Kassern
 
02.11.22
14:42
(18) А если первая версия будет 11.02.03, а вторая 11.2.03?
20 Бычье сердце
 
02.11.22
14:48
(19)
Что мешает предварительно убрать 0?
21 Chai Nic
 
02.11.22
14:50
Могу дать вредный совет. Сериализовать оба массива и сравнить полученные строки. )
22 Kassern
 
02.11.22
14:54
(20) класс. версия 10.11.30 и версия 01.11.03. Если убрать нули то прям красота получается)
23 Бычье сердце
 
02.11.22
14:56
(0)
С вашим мышлением да)))
Достаточно добавить "."
24 Бычье сердце
 
02.11.22
14:56
(23)
к (22)
25 Kassern
 
02.11.22
15:00
(24) Есть типовая функция которая сверяет версии. Там все грамотно сделано. Получается массив частей версий приводятся к числу и вычитается один из другого, если результат положительный - значит версия выше, если отрицательный -ниже, если результат равен 0, значит версии одинаковые.
26 Kassern
 
02.11.22
15:01
(23) С вашей логикой в (22) одинаковые версии, что не верно.
27 Бычье сердце
 
02.11.22
15:06
(25) Если речь идет о версиях 1С, то грамотно))))
(26) Тоже самое с логикой в (19)
28 Serg_1960
 
02.11.22
15:11
(27) "Если речь идет о версиях 1С" - это не принципиальный вопрос. Хотя автор и не говорил из каких именно символов состоит версия, - предпоследняя строка его кода намекает - только из цифр.
29 Kassern
 
02.11.22
15:13
(28) да тут 99% речь про версию в 1с.
Там так же 4 разряда проходят в типовой функции
Для Разряд = 0 По 3 Цикл
30 Бычье сердце
 
02.11.22
15:15
(28), (29)
Хорошо, хорошо, я вас удовлетворю, пусть это будут версии 1С)))
С намеками или без)))
31 Serg_1960
 
02.11.22
15:29
PS: если учесть новые возможности СтрНайти(), то версия из строкового в числовое значение преобразуется одной строкой, - весь код сравнения можно написать тремя лаконичными строками.
32 Ivan_495
 
02.11.22
15:34
если сравнивать версии, то массив не нужен, наоборот разделитель убрал к чисоу привел и сравнил
33 lamme
 
02.11.22
15:38
// Сравнивает два массива однотипных значений (кроме коллекций значений)
//
// Параметры:
//  ПервыйМассив,ВторойМассив - сравниваемые массивы
//
// Возвращаемое значение:
//  булево.
//
Функция МассивыИдентичны(ПервыйМассив,ВторойМассив) Экспорт

    ЭлементовМассива = ПервыйМассив.Количество();
    МассивыСовпадают = (ЭлементовМассива = ВторойМассив.Количество());
      
    Если МассивыСовпадают Тогда
        Для Сч = 1 По ЭлементовМассива Цикл
            Если ПервыйМассив[Сч-1] <> ВторойМассив[Сч-1] Тогда
                Возврат Ложь
            КонецЕсли;
        КонецЦикла;         
    КонецЕсли;

    Возврат МассивыСовпадают

КонецФункции



источник
https://helpf.pro/faq8/view/98.html
34 Serg_1960
 
02.11.22
15:39
(32) и (33) Вы невнимательно читали тему :)
35 polosov
 
02.11.22
15:51
РазделениеПервойВерсии = СтрРазделить(ПерваяВерсия,".");
РазделениеВторойВерсии = СтрРазделить(ВтораяВерсия,".");

Редакция = Новый Массив;

Для Индекс = 0 По РазделениеПервойВерсии.ВГраница() Цикл

Редакция[Иднекс] = Макс(РазделениеПервойВерсии[Индекс],РазделениеВторойВерсии[Индекс]);


КонецЦикла;

...
...
36 polosov
 
02.11.22
15:53
Редакция[Иднекс] = Макс(РазделениеПервойВерсии[Индекс],РазделениеВторойВерсии[Индекс]); ==> Редакция.Добавить(Макс(РазделениеПервойВерсии[Индекс],РазделениеВторойВерсии[Индекс]) )
37 Kesim
 
02.11.22
16:08
(0) Для Индекс = 0 По 3 Цикл
        Если РазделениеПервойВерсии[0] > РазделениеВторойВерсии[0] Тогда
            Редакция = РазделениеПервойВерсии;
            Продолжить;
        ИначеЕсли
При выполнении первого условия, в каждой итерации цикла  будет заходить именно сюда и дальше не продвинется.
поэтому упрощать именно этот код бесполезно. в зависимости от входящих условий решения будут разные.
выдать макс редакцию например:  

        РаздПВ = СтрРазделить(ПерваяВерсия,".");
    РаздВВ = СтрРазделить(ВтораяВерсия,".");
    
    Редакция = Неопределено;  
    ТекстСообщения = "Версии программ равны!";
    
    Если РаздПВ[0] <> РаздВВ[0] Тогда
        Редакция = ?(РаздПВ[0] > РаздВВ[0], РаздПВ, РаздВВ);
    ИначеЕсли РаздПВ[1] <> РаздВВ[1] Тогда
        Редакция = ?(РаздПВ[2] > РаздВВ[2], РаздПВ, РаздВВ);
    ИначеЕсли РаздПВ[3] <> РаздВВ[3] Тогда
        Редакция = ?(РаздПВ[3] > РаздВВ[3], РаздПВ, РаздВВ);
    КонецЕсли;
    
    Если Редакция <> Неопределено Тогда
        ТекстСообщения = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4",Число(Редакция[0]), Число(Редакция[1]), Число(Редакция[2]), Число(Редакция[3]));
    КонецЕсли;  
    
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = ТекстСообщения;
    Сообщение.Сообщить();
38 Kesim
 
02.11.22
16:09
(37) Индекса напутал, но идея думаю понятна
39 Kassern
 
02.11.22
16:19
(37)
Версия1 = СтрРазделить(Строка1, ".");
Версия2 = СтрРазделить(Строка2, ".");
Результат = 0;
    Для Разряд = 0 По 3 Цикл
        Результат = Число(Версия1[Разряд]) - Число(Версия2[Разряд]);
        Если Результат <> 0 Тогда
            Возврат Результат;
        КонецЕсли;
    КонецЦикла;
    Возврат Результат;
40 Kassern
 
02.11.22
16:20
Это из БСП без проверок
41 Mihasya
 
02.11.22
16:20
Хватит спорить, меньше не получается... и то тут нужно на преобразование в число проверять ))

&НаКлиенте
Процедура Сравнить(Команда)
    
    РазделениеПервойВерсии = СтрРазделить(СтрЗаменить("." + ЭтаФорма.ПерваяВерсия,".", ".0000000"), ".", Ложь);
    РазделениеВторойВерсии = СтрРазделить(СтрЗаменить("." + ЭтаФорма.ВтораяВерсия,".", ".0000000"), ".", Ложь);
    
    Редакция = Неопределено;
    Для а = 1 по Макс(РазделениеПервойВерсии.Количество(), РазделениеВторойВерсии.Количество()) Цикл
        ПерваяВерсияДляСравнения = Неопределено;
        ВтораяВерсияДляСравнения = Неопределено;
        Если а <= РазделениеПервойВерсии.Количество() Тогда
            ПерваяВерсияДляСравнения = Прав(РазделениеПервойВерсии[а-1], 7);
        КонецЕсли;
        Если а <= РазделениеВторойВерсии.Количество() Тогда
            ВтораяВерсияДляСравнения = Прав(РазделениеВторойВерсии[а-1], 7);
        КонецЕсли;
        Если ПерваяВерсияДляСравнения > ВтораяВерсияДляСравнения Тогда
            Редакция = РазделениеПервойВерсии;
            Прервать;
        ИначеЕсли ВтораяВерсияДляСравнения > ПерваяВерсияДляСравнения Тогда
            Редакция = РазделениеВторойВерсии;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    Если Редакция = Неопределено Тогда
        Текст = "Версии равны";
    Иначе
        Текст = "";
        Если Редакция.Количество() > 3 Тогда
            Текст = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4", Число(Редакция[0]), Число(Редакция[1]), Число(Редакция[2]), Число(Редакция[3]));
        ИначеЕсли Редакция.Количество() > 2 Тогда
            Текст = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4", Число(Редакция[0]), Число(Редакция[1]), Число(Редакция[2]), "?");
        ИначеЕсли Редакция.Количество() > 1 Тогда
            Текст = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4", Число(Редакция[0]), Число(Редакция[1]), "?", "?");
        ИначеЕсли Редакция.Количество() > 0 Тогда
            Текст = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4", Число(Редакция[0]), "?", "?", "?");
        КонецЕсли;
            
    КонецЕсли;
    
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = Текст;
    Сообщение.Сообщить();
    
КонецПроцедуры
42 Кирпич
 
02.11.22
17:01
Я чота не понимаю, зачем так всё запутано. Почему нельзя просто сравнить версии? Макс(ПерваяВерсия,ВтораяВерсия)
43 Kassern
 
02.11.22
17:03
(42) имхо из-за нулей. Как я и писал выше версия1 23.10.01 и версия2  23.10.1 по идее должны быть равны.
44 SilentMan
 
02.11.22
17:05
(0) Если в строках - версии вида "1.2.3.4", то я-бы преобразовал их в число (помня о "ширине" каждого элемента версии), а потом сравнил числа.
45 Кирпич
 
02.11.22
17:06
(43) А вывести надо самую большую или чего?
46 Mihasya
 
02.11.22
17:08
(43) Правильно, а версия 23.10.01 должна быть выше чем 23.9.01
47 Kassern
 
02.11.22
17:11
(45) как я понял, понять, одинаковые это версии, или нет, если не одинаковые, то версия2 выше, или ниже версии1. Тут все это дело реализовано (39)
48 Mihasya
 
02.11.22
17:16
(47) а как отработает код в 39 при условии:
1 - 3.1.25
2 - 3.1.25.2
?
49 Kassern
 
02.11.22
17:18
(48) никак, он заточен под версии 1с. Там еще проверка, чтобы обе версии имели только 4 разряда, в противном случае лови ВызватьИсключение
50 Kassern
 
02.11.22
17:19
и судя по топику ТС в (0) "Для Индекс = 0 По 3 Цикл " - у него так же 4 разряда.
51 Serg_1960
 
02.11.22
17:32
Игры разума: если предположить, что формат версии "Х.Х.Х.Х", где "Х" - числа от 0 до 999, то версию из строки можно преобразовать в число одной строкой кода :)

Возврат Число(Лев(ВерсияСтр,СтрНайти(ВерсияСтр,".",,,2)-1))*1000000+Число(Прав(ВерсияСтр,СтрДлина(ВерсияСтр)-СтрНайти(ВерсияСтр,".",,,2)));
52 Кирпич
 
02.11.22
17:32
во сочинил

Процедура СравнитьВерсии(ПерваяВерсияВх,ВтораяВерсияВх)  
    М = СтрРазделить(ПерваяВерсияВх,".");
    Для а = М.Количество() По 4 Цикл
        М.Добавить("0");
    КонецЦикла;    
    ПерваяВерсия = Число(СтрШаблон("%1%2%3%4",Число(М[0]),Число(М[1]),Число(М[2]),Число(М[3])));
    
    М = СтрРазделить(ВтораяВерсияВх,".");
    Для а = М.Количество() По 4 Цикл
        М.Добавить("0");
    КонецЦикла;    
    ВтораяВерсия = Число(СтрШаблон("%1%2%3%4",Число(М[0]),Число(М[1]),Число(М[2]),Число(М[3])));    

    Если ПерваяВерсия = ВтораяВерсия Тогда
        Сообщить("Версии равны");
        Возврат;
    КонецЕсли;  
      
    М = СтрРазделить(?(Макс(ПерваяВерсия,ВтораяВерсия)=ПерваяВерсия,ПерваяВерсияВх,ВтораяВерсияВх),".");
    Для а = М.Количество() По 4 Цикл
        М.Добавить("?");
    КонецЦикла;
    Сообщить(СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4",М[0],М[1],М[2],М[3]));    
КонецПроцедуры

53 Ivan_495
 
02.11.22
17:49
.0 меняем на пробел,
. меняем на пробел
сравниваем два числа
54 Ivan_495
 
02.11.22
17:49
меняем на ""
55 Mihasya
 
02.11.22
17:53
(47) код (41) норм отработает ))
56 Кирпич
 
02.11.22
18:22
(53)Не катит
001.001 = 00101
1.1 = 11
57 Ivan_495
 
02.11.22
18:38
даже если я добавлю еще три команды заменить .00 и .000 на ""
кода будет меньше
58 Ivan_495
 
02.11.22
18:38
первые нули уйдут при преобразовании в чмсло
59 Ivan_495
 
02.11.22
18:39
5 команд
60 rphosts
 
02.11.22
18:44
ВерсияПервая = РазделениеПервойВерсии[0]*1000000+РазделениеПервойВерсии[1]*10000+РазделениеПервойВерсии[2]*100+РазделениеПервойВерсии[3];
ВерсияВторая = РазделениеВторойВерсии[0]*1000000+РазделениеВторойВерсии[1]*10000+РазделениеВторойВерсии[2]*100+РазделениеВторойВерсии[3];
Если ВерсияПервая>ВерсияВторая Тогда
    Сообщить(1);
ИначеЕсли ВерсияПервая<ВерсияВторая Тогда
    Сообщить(1);
Иначе
    Сообщить("=");
КонецЕсли;
61 rphosts
 
02.11.22
18:45
Второе Сообшить(1) = Сообщить(2)
62 rphosts
 
02.11.22
18:46
если нужно ещё короче - можно вместо всего что начиная в 3 строке:
63 rphosts
 
02.11.22
18:47
Сообщить(?(ВерсияПервая=ВерсияВторая, "=", ?(ВерсияПервая>ВерсияВторая,"1","2")));
64 Ivan_495
 
02.11.22
18:49
1.2.0.4
0 × 100 =0
65 Кирпич
 
02.11.22
18:52
(59) О так будет универсально. Хоть 100 нулей

Процедура СравнитьВерсии(ПерваяВерсияВх,ВтораяВерсияВх)  
            
    ПерваяВерсия = ПерваяВерсияВх;
    Пока СтрНайти(ПерваяВерсия,".0") <> 0 Цикл  
        ПерваяВерсия = СтрЗаменить(ПерваяВерсия,".0",".");
    КонецЦикла;  
    ПерваяВерсия = Число(СтрЗаменить(ПерваяВерсия,".",""));
        
    ВтораяВерсия = ВтораяВерсияВх;
    Пока СтрНайти(ПерваяВерсия,".0") <> 0 Цикл  
        ВтораяВерсия = СтрЗаменить(ВтораяВерсия,".0",".");
    КонецЦикла;  
    ВтораяВерсия = Число(СтрЗаменить(ВтораяВерсия,".",""));    
        
    Если ПерваяВерсия = ВтораяВерсия Тогда
        Сообщить("Версии равны");
        Возврат;
    КонецЕсли;  
    
    М = СтрРазделить(?(Макс(ПерваяВерсия,ВтораяВерсия)=ПерваяВерсия,ПерваяВерсияВх,ВтораяВерсияВх),".");
    Для а = М.Количество() По 4 Цикл
        М.Добавить("?");
    КонецЦикла;
    Сообщить(СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4",М[0],М[1],М[2],М[3]));    
КонецПроцедуры
66 Ivan_495
 
02.11.22
18:58
стрзаменить заменяет все вхождения, циклы не нужны
67 Ivan_495
 
02.11.22
18:59
замену оформить отлельной функцией
68 Кирпич
 
02.11.22
21:15
(66) цикл нужен чтобы заменить все ведущие нули, а не только ".0"
69 Mihasya
 
03.11.22
02:34
(60) а если ВерсияПервая  = "1.2.3", конструкция РазделениеПервойВерсии[3] на индекс не ругнется?
70 Serg_1960
 
03.11.22
11:47
Игры разума: а теперь с типизацией, цифро-независимостью, сборно/разборная :)

    Разделитель = ".";
    Заполнитель = "0";
    
    Мах = Макс(СтрЧислоВхождений(ВерсияА, Разделитель), СтрЧислоВхождений(ВерсияБ, Разделитель), 3);
    
    Пока СтрЧислоВхождений(ВерсияА, Разделитель) < Мах Цикл
        ВерсияА = ВерсияА + Разделитель + Заполнитель;
    КонецЦикла;
    Пока СтрЧислоВхождений(ВерсияБ, Разделитель) < Мах Цикл
        ВерсияБ = ВерсияБ + Разделитель + Заполнитель;
    КонецЦикла;
    
    Версия1 = СтрРазделить(ВерсияА, Разделитель); ВерсияА = "";
    Версия2 = СтрРазделить(ВерсияБ, Разделитель); ВерсияБ = "";
    
    Для Индекс = 0 По Мах Цикл
        Пока СтрДлина(Версия1[Индекс]) < СтрДлина(Версия2[Индекс]) Цикл
            Версия1[Индекс] = Заполнитель + Версия1[Индекс];
        КонецЦикла;
        Пока СтрДлина(Версия2[Индекс]) < СтрДлина(Версия1[Индекс]) Цикл
            Версия2[Индекс] = Заполнитель + Версия2[Индекс];
        КонецЦикла;
        Версия1[Индекс] = ВРег(Версия1[Индекс]);
        Версия2[Индекс] = ВРег(Версия2[Индекс]);
        ВерсияА = ВерсияА + ?(Индекс=0, "", Разделитель) + Версия1[Индекс];
        ВерсияБ = ВерсияБ + ?(Индекс=0, "", Разделитель) + Версия2[Индекс];
    КонецЦикла;
    
    Если ВерсияА = ВерсияБ Тогда
        Результат = "Версии программ равны!";
    Иначе
        Редакция = ?(ВерсияА > ВерсияБ, Версия1, Версия2);
        Результат = СтрШаблон("Редакция %1 подредакция %2 версия %3 сборка %4", Редакция[0], Редакция[1], Редакция[2], Редакция[3]);
    КонецЕсли;
71 Kassern
 
03.11.22
11:56
Интересно, когда с побитовыми операциями вариант предложат?)
72 lodger
 
03.11.22
13:35
(71) падажжите, ещё Символ() не было!