Использование csv-файла для импорта данных в service manager

Импорт элементов конфигурации из CSV-файла

Перед импортом данных из файла с разделителями-запятыми (CSV) необходимо создать два файла: файл данных и файл форматирования. Для импорта файла Newcomputers.csv с использованием файла формата Newcomputers.xml можно использовать следующую процедуру.

Импорт элементов конфигурации из CSV-файла

  1. В консоли Service Manager щелкните элемент Администрирование.

  2. В области Администрирование разверните узел Администрированиеи выберите пункт Соединители.

  3. В области Задачи выберите команду Импортировать из CSV-файла.

  4. В диалоговом окне Импорт экземпляров из CSV-файла выполните следующие действия.

    1. Нажмите кнопку Обзор рядом с полем XML-файл форматаи выберите файл формата. Например, выберите файл Newcomputers.xmlи нажмите кнопку Открыть.

    2. Нажмите кнопку Обзор рядом с полем Файл данныхи выберите файл данных. Например, выберите файл Newcomputers.csvи нажмите кнопку Открыть.

  5. В диалоговом окне Импорт экземпляров из CSV-файла нажмите кнопку Импорт.

  6. В диалоговом окне Импорт экземпляров из CSV-файла убедитесь, что числа рядом с полями Сохранено элементов, Экземпляров, созданных в памятии Экземпляров, зафиксированных в базе данных совпадает с числом строк в файле данных, и нажмите кнопку Закрыть.

для выполнения этой задачи можно использовать команду Windows PowerShell. Сведения об импорте элементов конфигурации из CSV-файла с помощью Windows PowerShell см. в разделе Import-SCSMInstance.

Проверка импорта элементов конфигурации из CSV-файла

  1. В консоли Service Manager щелкните Элементы конфигурации.

  2. В области Элементы конфигурации разверните узлы Элементы конфигурациии Компьютеры, а затем выберите пункт Все компьютеры Windows.

  3. Убедитесь, что в области Все компьютеры Windows перечислены компьютеры из CSV-файла.

Импорт элементов конфигурации из CSV-файла

Перед импортом данных из файла с разделителями-запятыми (CSV) необходимо создать два файла: файл данных и файл форматирования. Для импорта файла Newcomputers.csv с использованием файла формата Newcomputers.xml можно использовать следующую процедуру.

Импорт элементов конфигурации из CSV-файла

  1. В консоли Service Manager щелкните элемент Администрирование.

  2. В области Администрирование разверните узел Администрированиеи выберите пункт Соединители.

  3. В области Задачи выберите команду Импортировать из CSV-файла.

  4. В диалоговом окне Импорт экземпляров из CSV-файла выполните следующие действия.

    1. Нажмите кнопку Обзор рядом с полем XML-файл форматаи выберите файл формата. Например, выберите файл Newcomputers.xmlи нажмите кнопку Открыть.

    2. Нажмите кнопку Обзор рядом с полем Файл данныхи выберите файл данных. Например, выберите файл Newcomputers.csvи нажмите кнопку Открыть.

  5. В диалоговом окне Импорт экземпляров из CSV-файла нажмите кнопку Импорт.

  6. В диалоговом окне Импорт экземпляров из CSV-файла убедитесь, что числа рядом с полями Сохранено элементов, Экземпляров, созданных в памятии Экземпляров, зафиксированных в базе данных совпадает с числом строк в файле данных, и нажмите кнопку Закрыть.

для выполнения этой задачи можно использовать команду Windows PowerShell. Сведения об импорте элементов конфигурации из CSV-файла с помощью Windows PowerShell см. в разделе Import-SCSMInstance.

Проверка импорта элементов конфигурации из CSV-файла

  1. В консоли Service Manager щелкните Элементы конфигурации.

  2. В области Элементы конфигурации разверните узлы Элементы конфигурациии Компьютеры, а затем выберите пункт Все компьютеры Windows.

  3. Убедитесь, что в области Все компьютеры Windows перечислены компьютеры из CSV-файла.

Модули для чтения и записи

Модуль CSV имеет несколько функций и классов, доступных для чтения и записи CSV, и они включают в себя:

  • функция csv.reader
  • функция csv.writer
  • класс csv.Dictwriter
  • класс csv.DictReader

csv.reader

Модуль csv.reader принимает следующие параметры:

  • : обычно это объект, который поддерживает протокол итератора и обычно возвращает строку каждый раз, когда вызывается его метод .
  • : необязательный параметр, используемый для определения набора параметров, специфичных для определенного диалекта CSV.
  • : необязательный параметр, который можно использовать для переопределения существующих параметров форматирования.

Вот пример того, как использовать модуль csv.reader.

модуль csv.writer

Этот модуль похож на модуль csv.reader и используется для записи данных в CSV. Требуется три параметра:

  • : это может быть любой объект с методом .
  • : необязательный параметр, используемый для определения набора параметров, специфичных для конкретного CSV.
  • : необязательный параметр, который можно использовать для переопределения существующих параметров форматирования.

Инверсия управления спешит на помощь

Учитывая размытость стандарта CSV, не практично писать универсальное средство разбора для всех случаев. Гораздо разумнее писать средство разбора, подходящее для конкретных потребностей какого-либо приложения. Используя инверсию управления (Inversion of Control), вы можете адаптировать механизм разбора под конкретные требования.

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

После этого я добавляю в класс CSVParser следующее свойство:

И предлагаю разработчикам выбор: использовать средство разбора по умолчанию или встроить собственное. Чтобы упростить эту задачу, я перегрузил конструктор:

Теперь класс CSVParser предоставляет базовую инфраструктуру, а реальная логика синтаксического анализа содержится в интерфейсе IParserEngine. Для удобства разработчиков я создал DefaultParserEngine, который может обрабатывать большинство CSV-файлов.

Проектирование средства разбора CSV универсального назначения

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

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

Эти общие черты обрисовывают универсальный алгоритм, который работал бы в три этапа.

  1. Разбиваем файл на строки по разделителю строк.
  2. Разбиваем каждую строку по разделителю полей.
  3. Присваиваем значение каждого поля какой-то переменной.

Это можно было бы реализовать сравнительно легко. Код на рис. 1 разбирает входную строку CSV в List<Dictionary<string, string>>.

Рис. 1. Разбор входной строки CSV в List<Dictionary<string,string>>

Этот подход отлично работает на примере следующего списка офисов, числа сотрудников и объемов продаж:

Чтобы получить значения из строки (string), вы должны были бы перебирать List и извлекать значения в Dictionary, используя индексацию полей от нуля. Например, получение поля офиса выглядело бы так:

Хотя это работает, код не столь читаем, каким мог бы быть.

Как проверять эффективность рич-контента

Рич-контент — достаточно сложное техническое и графическое решение. И прежде чем использовать его, стоит запланировать исследования, чтобы оценить контент с разных сторон и сделать его максимально привлекательным для пользователей.

Маркетинговые исследования для товара

Сравнение контента, цен и наличия товара с конкурентами можно осуществить с помощью систем для товарной аналитики. Например, платформа ECI мониторит миллионы товаров от 600 брендов на всех крупнейших торговых площадках в рунете и показывает, где, когда, что и по какой цене было представлено, каким было соотношение цен и игроков в категории, где и когда товары были в наличии, с помощью какого контента они были представлены пользователю и нет ли в нём ошибок. Например, маркетплейсы и ритейлеры могут использовать старые версии текстов или вообще не подходящие — перепутанные — картинки. Вручную это вычитать и обнаружить практически невозможно.

Сравнивая свои результаты с этими данными, можно ежедневно тестировать новые и новые улучшения. Бонус ещё и в том, что системы товарной аналитики мониторят отзывы и собирают их со всех площадок в одну базу. Это пригодится для работы с отзывами и для сборки рич-контента.

A/B-тестирование эффективности контента

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

Это исследование можно провести самостоятельно и для любого элемента карточки товара. Методика несложная: нужно сравнить привлекательность двух и более макетов для пользователей, направив одинаковый и непересекающийся трафик на каждый их них.

Перед началом исследования товарного контента нужно точно определить тестируемую гипотезу и метрики эффективности: например, длительность нахождения пользователя на странице, количество просмотров на странице, количество добавлений в корзину и покупок.

UX-исследования

С их помощью узнаём:

  • как пользователь выбирает товар,
  • понятен ли ему прототип карточки товара,
  • какие эмоции он испытывает на каждом экране,
  • какие ошибки можно допустить в понимании контента и чего не хватает,
  • хорошо ли работают элементы управления, удобны ли они,
  • находят ли отклик у покупателей имиджевые тексты, видео и картинки.

Помогут качественные и количественные исследования — на старте, во время разработки идеи и после запуска и тестирования нового формата контента.

Подходящая методика зависит от стадии развития проекта и задач на данный момент. Стоит присмотреться к методикам проведения глубинных интервью, если нужно выяснить множество деталей о поведении и решениях пользователя. На основе результатов таких интервью вы сможете сделать карту эмпатии и Customer Journey Map, разработать логику повествования о товаре на странице и использовать в контенте нужные аргументы «за».

Поведение пользователей на уже готовой странице можно изучить с помощью First click test, а удовлетворённость клиентов в разрезе каждого блока информации или сервиса — по методике Кано.

Профессиональный UX-исследователь подберёт доступные и подходящие конкретным бизнес-задачам методики исследования и организует их проведение.

Диалекты и форматирование

Диалект — это вспомогательный класс, используемый для определения параметров для конкретного экземпляра  или . Диалекты и параметры форматирования должны быть объявлены при выполнении функции чтения или записи.

Есть несколько атрибутов, которые поддерживаются диалектом:

  • delimiter: строка, используемая для разделения полей. По умолчанию это .
  • double quote: Управляет тем, как должны появляться в кавычках случаи, когда кавычки появляются внутри поля. Может быть True или False.
  • escapechar: строка, используемая автором для экранирования разделителя, если в кавычках задано значение .
  • lineterminator: строка, используемая для завершения строк, созданных . По умолчанию используется значение .
  • quotechar: строка, используемая для цитирования полей, содержащих специальные символы. По умолчанию это .
  • skipinitialspace: Если установлено значение , любые пробелы, следующие сразу за разделителем, игнорируются.
  • strict: если установлено значение , возникает при неправильном вводе CSV.
  • quoting: определяет, когда следует создавать кавычки при чтении или записи в CSV.

Какие форматы рич-контента наиболее эффективны

Один из вариантов — воспользоваться опытом других брендов и копировать решения лучших конкурентов в оформлении карточек.

Если говорить о рич-контенте, то для подбора инструментов и его форматов продавцу нужно как можно подробнее узнать, что для разной аудитории определяет выбор его продукта, — и готовить карточки товара с данными на базе этой информации. Это знание поможет продавцу составить эффективную карточку и создать яркий рич-контент на своей площадке d2c (Direct-to-Consumer) или на маркетплейсе.

Давайте посмотрим, чем можно наполнить рич-контент.

Увлекательные и содержательные тексты-истории расскажут об особенностях товара

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

История становится интересной, если в ней есть хоть немного драматургии — эмоций, которые выражаются не канцелярским сухим языком, а художественно, с использованием прилагательных, простых и понятных оборотов речи, шуток.

Чтение CSV-файла при помощи csv.reader(). Метод 1

Пример 1. Использование запятой в качестве разделителя

Допустим, у нас есть файл с именем sample1, содержащий некоторые данные. Такой файл можно создать с помощью любого текстового редактора или путем передачи значений в какую-нибудь программу для записи файла CSV. Как это делается, мы расскажем чуть позже.

Текст в этом файле разделен запятыми. Наши данные — сведения о различных книгах (порядковый номер, название, имя автора).

Переходим к коду. Чтобы прочитать файл CSV, нам нужен объект reader для выполнения функции чтения. Первым делом импортируем модуль (встроенный модуль Python). Далее укажем имя файла, который нужно открыть (или путь к нему). Затем инициализируем объект . Он будет перебираться в цикле .

reader = csv.reader(файл)

Данные из указанного файла выводятся построчно.

Запустим наш код. Можем увидеть, что наши данные автоматически преобразовались в списки, состоящие из элементов данных каждой строки.

Пример 2. Использование табуляции в качестве разделителя

В первом примере текст разделяется запятой. Однако мы можем сделать наш код более настраиваемым, добавив различные функции.

Возьмём код из предыдущего примера и сделаем лишь одно изменение: напрямую укажем разделитель (). В предыдущем примере не было никакой необходимости его указывать, потому что запятая — разделитель по умолчанию.

reader = csv.reader(file, delimiter = ‘\t’)

Как видите, результат немного изменился. Теперь все элементы строки являются одним элементом списка. Так произошло потому, что в этот раз мы указали в качестве разделителя не запятую, а .

Элемент «Задание»

«Задание» это простой в использовании учебный элемент системы Moodle, являющийся эффективным средством методической и организационной поддержки самостоятельной работы студентов по освоению конкретных разделов учебной дисциплины.

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

Реализуемый в электронной среде Moodle учебный элемент «Задание» позволяет использовать этот эффективный педагогический прием, без использования «бумажных» технологий, максимально используя коммуникационные преимущества электронной учебной среды.

Учебный элемент «Задание» позволяет реализовывать следующие возможности:

—    формирование преподавателем для предоставления студентам задания на выполнение определенной учебной работы в рамках соответствующей темы курса;

—    установку преподавателем ограничений видимости и доступности задания для студентов, как в рамках определенного временного периода, так и в зависимости от степени успешности выполнения ими какого-либо другого задания или оцениваемого учебного элемента курса;

—    предоставление студентами результатов выполнения задания в разнообразных цифровых форматах;

—    автоматическое уведомление преподавателя по электронной почте о размещении студентом файла(-ов) своей работы по заданию и уведомление студента о наличии отзыва и оценки за присланную им работу;

—    возможность для преподавателя оценивания представленных студентами работ, в том числе и использования нескольких оценок по различным показателям, например, за полноту решения задачи, оригинальность решения, оформление работы и т. д.;

—    возможность для преподавателя направлять студенту отрецензированный файл с отмеченными указаниями о сделанных ошибках и вопросами по контексту задания, в том числе возможность аннотирования файлов работ, присланных в формате PDF;

—    использование «Задания» для фиксации результатов работ выполненных вне сайта в автономном режиме (например, при создании предметов искусства, работе с лабораторным оборудованием) без представления работы в цифровом виде;

—    возможность для студента ответить преподавателю на полученные замечания в виде краткого комментария или путем присылки исправленного файла работы;

—    сохранение в базе данных системы присылаемых студентами работ, отзывов преподавателя и ответов студентов;

Чтение¶

Пример чтения файла в формате CSV (файл csv_read.py):

import csv

with open('sw_data.csv') as f
    reader = csv.reader(f)
    for row in reader
        print(row)

Вывод будет таким:

$ python csv_read.py





В первом списке находятся названия столбцов, а в остальных
соответствующие значения.

Обратите внимание, что сам csv.reader возвращает итератор:

In 1]: import csv

In 2]: with open('sw_data.csv') as f
   ...     reader = csv.reader(f)
   ...     print(reader)
   ...
<_csv.reader object at 0x10385b050>

При необходимости его можно превратить в список таким образом:

In 3]: with open('sw_data.csv') as f
   ...     reader = csv.reader(f)
   ...     print(list(reader))
   ...
, 'sw1', 'Cisco', '3750', 'London'], 'sw2', 'Cisco', '3850', 'Liverpool'], 'sw3', 'Cisco', '3650', 'Liverpool'], 'sw4', 'Cisco', '3650', 'London']]

Чаще всего заголовки столбцов удобней получить отдельным объектом. Это
можно сделать таким образом (файл csv_read_headers.py):

import csv

with open('sw_data.csv') as f
    reader = csv.reader(f)
    headers = next(reader)
    print('Headers: ', headers)
    for row in reader
        print(row)

Иногда в результате обработки гораздо удобней получить словари, в
которых ключи — это названия столбцов, а значения — значения столбцов.

Для этого в модуле есть DictReader (файл csv_read_dict.py):

import csv

with open('sw_data.csv') as f
    reader = csv.DictReader(f)
    for row in reader
        print(row)
        print(row'hostname'], row'model'])

Вывод будет таким:

$ python csv_read_dict.py
{'hostname': 'sw1', 'vendor': 'Cisco', 'model': '3750', 'location': 'London, Globe Str 1 '}
sw1 3750
{'hostname': 'sw2', 'vendor': 'Cisco', 'model': '3850', 'location': 'Liverpool'}
sw2 3850
{'hostname': 'sw3', 'vendor': 'Cisco', 'model': '3650', 'location': 'Liverpool'}
sw3 3650
{'hostname': 'sw4', 'vendor': 'Cisco', 'model': '3650', 'location': 'London, Grobe Str 1'}
sw4 3650

Рич-контент демонстрирует важную для покупателя информацию

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

Опыт более 400 брендов, с контентом которых работает Brandquad, показал, что рич-контент может добавить до 22% к конверсии в продажу для товаров, о которых пользователю, как правило, будет интересно узнать побольше фактов: например, для игрушек, украшений и бытовой техники.

С технической точки зрения рич-контент представляет собой способ вёрстки страниц о товарах, где можно использовать любые виды графики и текстов. Такой контент оформляют как HTML-код, картинку в формате jpeg или как код, описывающий положение элементов на странице в формате JSON (JavaScript Object Notation).

С помощью кодировки JSON можно в текстовом виде структурировать и передавать на сайт сложные данные рич-контента: тексты, фото, видео и любые другие данные. Такой формат технической вёрстки страниц с рич-контентом используется чаще всего.

Например, так поступают на Ozon, одном из крупнейших маркетплейсов России.


кода для вёрстки страницы с рич-контентом в JSON-формате. Контент страницы и его структура описываются текстом

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

Примеры нативной рекламы

Изготовление качественной нативной рекламы – это настоящее мастерство. Желательно подходить к процессу создания креативно и не забывать о золотом правиле – никакой навязчивости. А именно не переборщить с присутствием бренда в контексте и не стараться показать свою марку «в полный рост», а лишь мельком. Давайте посмотрим на примеры нативной рекламы, которые могут вдохновить на создание не менее крутых шедевров.

Очень много интеграций с брендами делает журнал Тинькофф и создает совместно с ними различные игры. Вот например, симулятор такси, созданный совместно с Ситимобил. Отличный интерактив, где можно и поиграть, и за подарки побороться.

Еще был отличный проект в виде теста совместно со ВкусВилл. Забавная штука, в которой хоть и есть упоминание бренда, но отсутствует прямая реклама.

Очень хорошо разошелся проект General Electrics со своей серией подкастов «The Message». Эдакий научно-фантастический сериал на 8 недель, где участники изучали некие «послания из глубокого космоса». Он даже стал лауреатом премии Webby за лучшее использование нативной рекламы в 2016 году.

У легендарного «отца рекламы» Дэвида Огилви тоже был удачный пример нативки, называемый «Путеводитель по устрицам» (на самом деле, это была реклама пива Guinness). Чуть позже был выпущен «Путеводитель по сырам», выполненный в похожем формате.

Нативная реклама – эффективный и ненавязчивый инструмент, ориентированный на ценности потребителей. Если правильно его использовать, можно в разы увеличить аудиторию и ее доверие к вам. Экспериментируйте! 

Резюмируем

Рич-контент даёт широкие возможности для творчества и привлечения внимания покупателей. Изучение пользователей поможет выбрать инструменты представления рич-контента и подстроить их под запрос покупателей.

Тексты о товаре лучше писать как истории с эмоциональным зарядом. При этом они не должны уводить покупателей от основной мысли.

Стоит использовать рендеры 3D-моделей и фото 360⁰, чтобы ярче показать особенности товара. В первую очередь это относится к продукции, которую тяжело или невозможно сфотографировать.

Для технически сложных товаров стоит использовать схемы, инфографику и пояснения — всё, что сделает товар понятнее для покупателя.

Забота о людях с ограниченными возможностями благотворно скажется на репутации компании и удовлетворённости пользователей, особенно если речь идёт о товарах для людей с ограничениями по здоровью.

Для управления данными для рич-контента лучше использовать PIM- и DAM-каталоги. Это позволит пользоваться актуальными данными о товарах и передавать их ритейлерам и на собственный сайт.

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

Можно и нужно измерять показатели работы рич-контента не только маркетинговыми, но и UX-методами.

Импорт данных из файлов с разделителями-запятыми

Элементы конфигурации, содержащиеся в файле значений с разделителями-запятыми (.csv), могут быть импортированы в базу данных Service Manager с помощью функции импорта из CSV-файла. Эта функция позволяет выполнять массовый импорт экземпляров любого типа класса или проекции, определенного в базе данных Service Manager. Эта функция может использоваться для следующих операций.

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

  • Массовое изменение существующих экземпляров базы данных.

  • Заполнение Service Manager базы данных с помощью данных, экспортированных из внешней базы данных.

  • Сокращение объема данных, вводимых в формы при одновременном создании большого количества экземпляров класса.

Примечание

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

Для импорта набора экземпляров с помощью функции «Импорт из CSV-файла» требуются два файла.

  1. Файл данных, состоящий из последовательности экземпляров объектов, разделенных запятыми. Файл данных должен иметь расширение CSV.

  2. Файл форматирования, который указывает тип класса или тип проекции для экземпляров, присутствующих в файле данных. Каждый экземпляр в файле данных относится к этому виду. В файле форматирования также указывается (1) подмножество свойств, а для проекций указываются компоненты. Они импортируются для указанного типа. Кроме того, указывается (2) порядок, в котором эти свойства следуют в виде столбцов в связанном в файле данных. Файл форматирования должен иметь расширение XML, а его имя должно совпадать с именем CSV-файла, который описывает файл форматирования.

Запись в файл CSV

Давайте теперь посмотрим, как приступить к записи данных в файл CSV с использованием функции и класса , которые обсуждались в начале этого урока.

Запись в файл CSV с помощью csv.writer

Код ниже записывает данные, определенные в файл .

Сначала мы импортируем модуль csv, и функция создаст объект, подходящий для записи. Чтобы перебрать данные по строкам, нам нужно использовать функцию .

Вот наш CSV с данными, которые мы записали в него.

Запись в файл CSV с использованием DictWriter

Давайте напишем следующие данные в CSV.

Код, как показано ниже.

Сначала мы определим , которые будут представлять заголовки каждого столбца в файле CSV. Метод будет записывать по одной строке за раз. Если вы хотите записать все данные одновременно, вы будете использовать метод .

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

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: