Ваши Вопросы

Как на графике в экселе поменять формат отображения чисел?

 

Как на графике Excel поменять формат отображения чисел?

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

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


Ряд данных без форматирования
Ряд данных без форматирования

Воспользуемся произвольным форматом в Excel, чтобы поменять формат чисел на млрд. Для этого выделяем ряд правой кнопкой и идём в «Формат ячеек».


Переходим в формат ячеек

Выбираем пункт «Все форматы» и пишем формат отображения.

# ##0,0   " млрд. ₽"


Ввод формата чисел для миллиардов
Ввод формата чисел для миллиардов

В зависимости от кол-ва пробелов между нулём и первыми кавычками (в примере их 3 для миллиардов) мы можем выводить разрядность тысяч (один пробел), миллионов (два пробела), миллиардов (три пробела) и т.д.


Ряд данных с форматом в млрд
Ряд данных с форматом в млрд

Замена формата чисел на графике Excel

Теперь построим по полученному ряду график и добавим отображение значений. Получится что-то такое.


Полученный график

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

Для выделяем значения на графике через правую кнопку и идём в «Формат подписей данных»


Формат подписей данных по умолчанию
Формат подписей данных по умолчанию

Меняем галочки на другие и получаем нормальное отображение.


Отображение чисел на графике в млрд.
Отображение чисел на графике в млрд.

Источник: https://pavezlo.ru/marketing/kak-na-grafike-excel-pomenyat-format-otobra...

 

 

Как пользоваться библиотекой Requests в Python?

Расскажите, как можно пользоваться библиотекой  Requests в питоне?

Прежде чем начать, убедитесь, что установлена последняя версия Requests.

    Для начала, давайте рассмотрим простые примеры.

    Создание GET и POST запроса

    Импортируйте модуль Requests:

    Попробуем получить веб-страницу с помощью get-запроса. В этом примере давайте рассмотрим общий тайм-лайн GitHub:

    r = requests.get('https://api.github.com/events')
    
    

    Мы получили объект Response с именем r. С помощью этого объекта можно получить всю необходимую информацию.

    Простой API Requests означает, что все типы HTTP запросов очевидны. Ниже приведен пример того, как вы можете сделать POST запрос:

    r = requests.post('https://httpbin.org/post', data = {'key':'value'})  
    
    

    Другие типы HTTP запросов, такие как : PUT, DELETE, HEAD и OPTIONS так же очень легко выполнить:

    r = requests.put('https://httpbin.org/put', data = {'key':'value'})  
    r = requests.delete('https://httpbin.org/delete')  
    r = requests.head('https://httpbin.org/get')  
    r = requests.options('https://httpbin.org/get')  
    
    

    Передача параметров в URL

    Часто вам может понадобится отправить какие-то данные в строке запроса URL. Если вы настраиваете URL вручную, эти данные будут представлены в нем в виде пар ключ/значение после знака вопроса. Например, httpbin.org/get?key=val. Requests позволяет передать эти аргументы в качестве словаря, используя аргумент params. Если вы хотите передать key1=value1 и key2=value2 ресурсу httpbin.org/get, вы должны использовать следующий код:

    payload = {'key1': 'value1', 'key2': 'value2'}  
    r = requests.get('https://httpbin.org/get', params=payload)
    print(r.url) 
    
    

    Как видно, URL был сформирован правильно:

    https://httpbin.org/get?key2=value2&key1=value1
    Ключ словаря, значение которого None, не будет добавлен в строке запроса URL.

      Вы можете передать список параметров в качестве значения:

      >>> payload = {'key1': 'value1', 'key2': ['value2', 'value3']}  
      >>> r = requests.get('https://httpbin.org/get', params=payload)  
      >>> print(r.url)  
      https://httpbin.org/get?key1=value1&key2=value2&key2=value3 
      
      

      Содержимое ответа (response)

      Мы можем прочитать содержимое ответа сервера. Рассмотрим снова тайм-лайн GitHub:

      >>> import requests
      >>> r = requests.get('https://api.github.com/events')
      >>> r.text
      '[{"repository":{"open_issues":0,"url":"https://github.com/...
      
      

      Requests будет автоматически декодировать содержимое ответа сервера. Большинство кодировок unicode декодируются без проблем.
      Когда вы делаете запрос, Requests делает предположение о кодировке, основанное на заголовках HTTP. Эта же кодировка текста, используется при обращение к r.text. Можно узнать, какую кодировку использует Requests, и изменить её с помощью r.encoding:

      >>> r.encoding
      'utf-8'
      >>> r.encoding = 'ISO-8859-1'
      
      

      Если вы измените кодировку, Requests будет использовать новое значение r.encoding всякий раз, когда вы будете использовать r.text. Вы можете сделать это в любой ситуации, где нужна более специализированная логика работы с кодировкой содержимого ответа.

      Например, в HTML и XML есть возможность задавать кодировку прямо в теле документа. В подобных ситуациях вы должны использовать r.content, чтобы найти кодировку, а затем установить r.encoding. Это позволит вам использовать r.text с правильной кодировкой.

      Requests может также использовать пользовательские кодировки в случае, если в них есть потребность. Если вы создали свою собственную кодировку и зарегистрировали ее в модуле codecs, используйте имя кодека в качестве значения r.encoding.

      Бинарное содержимое ответа

      Вы можете также получить доступ к телу ответа в виде байтов для не текстовых ответов:

      >>> r.content
      b'[{"repository":{"open_issues":0,"url":"https://github.com/...
      
      

      Передача со сжатием gzip и deflate автоматически декодируются для вас.

      Например, чтобы создать изображение на основе бинарных данных, возвращаемых при ответе на запрос, используйте следующий код:

      from PIL import Image  
      from io import BytesIO  
      
      i = Image.open(BytesIO(r.content))
      
      

      Содержимое ответа в JSON

      Если вы работаете с данными в формате JSON, воспользуйтесь встроенным JSON декодером:

      >>> import requests
      >>> r = requests.get('https://api.github.com/events')
      >>> r.json()
      [{'repository': {'open_issues': 0, 'url': 'https://github.com/...
      
      

      Если декодирование в JSON не удалось, r.json() вернет исключение. Например, если ответ с кодом 204 (No Content), или на случай если ответ содержит не валидный JSON, попытка обращения к r.json() будет возвращать ValueError: No JSON object could be decoded.

      Следует отметить, что успешный вызов r.json() не указывает на успешный ответ сервера. Некоторые серверы могут возвращать объект JSON при неудачном ответе (например, сведения об ошибке HTTP 500). Такой JSON будет декодирован и возвращен. Для того, чтобы проверить успешен ли запрос, используйте r.raise_for_status() или проверьте какой r.status_code.

      Необработанное содержимое ответа

      В тех редких случаях, когда вы хотите получить доступ к “сырому” ответу сервера на уровне сокета, обратитесь к r.raw. Если вы хотите сделать это, убедитесь, что вы указали stream=True в вашем первом запросе. После этого вы уже можете проделать следующее:

      >>> r = requests.get('https://api.github.com/events', stream=True)
      >>> r.raw
      <urllib3.response.HTTPResponse object at 0x101194810>
      >>> r.raw.read(10)
      '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'
      
      

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

      with open(filename, 'wb') as fd:
          for chunk in r.iter_content(chunk_size=128):
              fd.write(chunk)
      
      

      Использование r.iter_content обработает многое из того, с чем бы вам пришлось иметь дело при использовании r.raw напрямую. Для извлечения содержимого при потоковой загрузке, используйте способ, описанный выше. Обратите внимание, что chunk_size можно свободно скорректировать до числа, которое лучше подходит в вашем случае.

      Важное замечание об использовании Response.iter_content и Response.raw. Response.iter_content будет автоматически декодировать gzip и deflate. Response.raw — необработанный поток байтов, он не меняет содержимое ответа. Если вам действительно нужен доступ к байтам по мере их возврата, используйте Response.raw.

      Пользовательские заголовки

      Если вы хотите добавить HTTP заголовки в запрос, просто передайте соответствующий dict в параметре headers.
      Например, мы не указали наш user-agent в предыдущем примере:

      url = 'https://api.github.com/some/endpoint'  
      headers = {'user-agent': 'my-app/0.0.1'}  
      r = requests.get(url, headers=headers)
      
      

      Заголовкам дается меньший приоритет, чем более конкретным источникам информации. Например:

      • Заголовки авторизации, установленные с помощью headers= будут переопределены, если учетные данные указаны .netrc, которые, в свою очередь переопределены параметром auth=.
      • Они же будут удалены при редиректе.
      • Заголовки авторизации с прокси будут переопределены учетными данными прокси-сервера, которые указаны в вашем URL.
      • Content-Length будут переопределены, когда вы определите длину содержимого.

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

      Значения заголовка должны быть string, bytestring или unicode. Хотя это разрешено, рекомендуется избегать передачи значений заголовков unicode.

      Более сложные POST запросы

      Часто вы хотите послать некоторые form-encoded данные таким же образом, как это делается в HTML форме. Для этого просто передайте соответствующий словарь в аргументе data. Ваш словарь данных в таком случае будет автоматически закодирован как HTML форма, когда будет сделан запрос:

      >>> payload = {'key1': 'value1', 'key2': 'value2'}
      >>> r = requests.post("https://httpbin.org/post", data=payload)
      >>> print(r.text)
      {
        ...
        "form": {
          "key2": "value2",
          "key1": "value1"
        },
        ...
      }
      
      

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

      >>> payload_tuples = [('key1', 'value1'), ('key1', 'value2')]
      >>> r1 = requests.post('https://httpbin.org/post', data=payload_tuples)
      >>> payload_dict = {'key1': ['value1', 'value2']}
      >>> r2 = requests.post('https://httpbin.org/post', data=payload_dict)
      >>> print(r1.text)
      {
        ...
        "form": {
          "key1": [
            "value1",
            "value2"
          ]
        },
        ...
      }
      >>> r1.text == r2.text
      True
      
      

      Бывают случаи, когда нужно отправить данные не закодированные методом form-encoded. Если вы передадите в запрос строку вместо словаря, эти данные отправятся в не измененном виде.

      К примеру, GitHub API v3 принимает закодированные JSON POST/PATCH данные:

      import json
      
      url = 'https://api.github.com/some/endpoint'  
      payload = {'some': 'data'}  
      r = requests.post(url, data=json.dumps(payload))  
      
      

      Вместо того, чтобы кодировать dict, вы можете передать его напрямую, используя параметр json (добавленный в версии 2.4.2), и он будет автоматически закодирован:

      url = 'https://api.github.com/some/endpoint'  
      payload = {'some': 'data'}  
      r = requests.post(url, json=payload) 
      
      

      Обратите внимание, параметр json игнорируется, если передаются data или files.
      Использование параметра json в запросе изменит заголовок Content-Type на application/json.

      POST отправка Multipart-Encoded файла

      Запросы упрощают загрузку файлов с многостраничным кодированием (Multipart-Encoded) :

      >>> url = 'https://httpbin.org/post'
      >>> files = {'file': open('report.xls', 'rb')}
      >>> r = requests.post(url, files=files)
      >>> r.text
      {
        ...
        "files": {
          "file": "<censored...binary...data>"
        },
        ...
      }
      
      

      Вы можете установить имя файла, content_type и заголовки в явном виде:

      >>> url = 'https://httpbin.org/post'
      >>> files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
      >>> r = requests.post(url, files=files)
      >>> r.text
      {
        ...
        "files": {
          "file": "<censored...binary...data>"
        },
        ...
      }
      
      

      Можете отправить строки, которые будут приняты в виде файлов:

      >>> url = 'https://httpbin.org/post'
      >>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
      >>> r = requests.post(url, files=files)
      >>> r.text
      {
        ...
        "files": {
          "file": "some,data,to,send\\nanother,row,to,send\\n"
        },
        ...
      }
      
      

      В случае, если вы отправляете очень большой файл как запрос multipart/form-data, возможно понадобиться отправить запрос потоком. По умолчанию, requests не поддерживает этого, но есть отдельный пакет, который это делает — requests-toolbelt. Ознакомьтесь с документацией toolbelt для получения более детальной информации о том, как им пользоваться.

      Для отправки нескольких файлов в одном запросе, обратитесь к расширенной документации.

      Предупреждение!
      Настоятельно рекомендуется открывать файлы в бинарном режиме. Это связано с тем, что запросы могут пытаться предоставить для вас заголовок Content-Length, и если это значение будет установлено на количество байтов в файле будут возникать ошибки, при открытии файла в текстовом режиме.

      Коды состояния ответа

      Мы можем проверить код состояния ответа:

      >>> r = requests.get('https://httpbin.org/get')
      >>> r.status_code
      200
      
      

      У requests есть встроенный объект вывода кодов состояния:

      >>> r.status_code == requests.codes.ok
      True
      
      

      Если мы сделали неудачный запрос (ошибка 4XX или 5XX), то можем вызвать исключение с помощью r.raise_for_status():

      >>> bad_r = requests.get('https://httpbin.org/status/404')
      >>> bad_r.status_code
      404
      >>> bad_r.raise_for_status()
      Traceback (most recent call last):
        File "requests/models.py", line 832, in raise_for_status
          raise http_error
      requests.exceptions.HTTPError: 404 Client Error
      
      

      Но если status_code для r оказался 200, то когда мы вызываем raise_for_status() мы получаем:

      Заголовки ответов

      Мы можем просматривать заголовки ответа сервера, используя словарь Python:

      >>> r.headers
      {
          'content-encoding': 'gzip',
          'transfer-encoding': 'chunked',
          'connection': 'close',
          'server': 'nginx/1.0.4',
          'x-runtime': '148ms',
          'etag': '"e1ca502697e5c9317743dc078f67693f"',
          'content-type': 'application/json'
      }
      
      

      Это словарь особого рода, он создан специально для HTTP заголовков. Согласно с RFC 7230, имена заголовков HTTP нечувствительны к регистру.

      Теперь мы можем получить доступ к заголовкам с большим буквами или без, если захотим:

      >>> r.headers['Content-Type']
      'application/json'
      >>> r.headers.get('content-type')
      'application/json'
      
      

      Cookies

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

      >>> url = 'https://example.com/some/cookie/setting/url'
      >>> r = requests.get(url)
      >>> r.cookies['example_cookie_name']
      'example_cookie_value'
      
      

      Чтобы отправить собственные cookies на сервер, используйте параметр cookies:

      >>> url = 'https://httpbin.org/cookies'
      >>> cookies = dict(cookies_are='working')
      >>> r = requests.get(url, cookies=cookies)
      >>> r.text
      '{"cookies": {"cookies_are": "working"}}'
      
      

      Cookies возвращаются в RequestsCookieJar, который работает как dict, но также предлагает более полный интерфейс, подходящий для использования в нескольких доменах или путях. Словарь с cookie может также передаваться в запросы:

      >>> jar = requests.cookies.RequestsCookieJar()
      >>> jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
      >>> jar.set('gross_cookie', 'blech', domain='httpbin.org', path='/elsewhere')
      >>> url = 'https://httpbin.org/cookies'
      >>> r = requests.get(url, cookies=jar)
      >>> r.text
      '{"cookies": {"tasty_cookie": "yum"}}'
      
      

      Редиректы и история

      По умолчанию Requests будет выполнять редиректы для всех HTTP глаголов, кроме HEAD.

      Мы можем использовать свойство history объекта Response, чтобы отслеживать редиректы .

      Список Response.history содержит объекты Response, которые были созданы для того, чтобы выполнить запрос. Список сортируется от более ранних, до более поздних ответов.

      Например, GitHub перенаправляет все запросы HTTP на HTTPS:

      >>> r = requests.get('https://github.com/')
      >>> r.url
      'https://github.com/'
      >>> r.status_code
      200
      >>> r.history
      [<Response [301]>]
      
      

      Если вы используете запросы GET, OPTIONS, POST, PUT, PATCH или DELETE, вы можете отключить обработку редиректа с помощью параметра allow_redirects:

      >>> r = requests.get('https://github.com/', allow_redirects=False)
      >>> r.status_code
      301
      >>> r.history
      []
      
      

      Если вы используете HEAD, вы также можете включить редирект:

      >>> r = requests.head('https://github.com/', allow_redirects=True)
      >>> r.url
      'https://github.com/'
      >>> r.history
      [<Response [301]>]
      
      

      Тайм-ауты

      Вы можете сделать так, чтобы Requests прекратил ожидание ответа после определенного количества секунд с помощью параметра timeout.

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

      >>> requests.get('https://github.com/', timeout=0.001)
      Traceback (most recent call last):
        File "", line 1, in 
      requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
      
      

      Timeout это не ограничение по времени полной загрузки ответа. Исключение возникает, если сервер не дал ответ за timeout секунд (точнее, если ни одного байта не было получено от основного сокета за timeout секунд).

      Ошибки и исключения

      В случае неполадок в сети (например, отказа DNS, отказа соединения и т.д.), Requests вызовет исключение ConnectionError.

      Response.raise_for_status() вызовет HTTPError если в запросе HTTP возникнет статус код ошибки.

      Если выйдет время запроса, вызывается исключение Timeout. Если запрос превышает заданное значение максимального количества редиректов, то вызывают исключение TooManyRedirects.

      Все исключения, которые вызывает непосредственно Requests унаследованы от requests.exceptions.RequestException.

       

      Источник: https://pythonru.com/biblioteki/kratkoe-rukovodstvo-po-biblioteke-python...

      Как отключить автоматическую прокрутку в VSCode Live Server?

      VSCode Live Server: Disable scroll up on save

      При использовании расширения Live Server для VS Code, замечали одну неприятную особенность.

      Когда вы вносите изменения в код и сохраняетесь, страница прокручивается в начало. И если вы работали с блоками где-то посередине вам приходится каждый раз возвращаться к ним снова. Это неудобно если нужно сделать какие-то мелкие правки и до/после необходимо видеть сразу же.

      Чтобы изменить это поведение, перейдите в File > Preferences > Settings
      В списке Commonly Used выберете Extensions > Live Server Config
      Найдите пункт Settings: Full Reload
      и поставьте галочку ☑

      Перезагрузите VS Code и вуаля. Страница перезагружается оставаясь на том же месте с которым вы работаете в данный момент.

      Альтернативные способы

      Через поиск:
      Открыть настройки через Ctrl + , (запятая в англиской раскладке)

      Ввести в поиск:
      liveServer.settings.fullReload

      Поставить галочку ☑
      Перезагрузить VS Code.

      Через settings.json:
      В файле настроек редактора settings.json между фигурными скобками вставить:

      "liveServer.settings.fullReload": true,

      Не забудьте запятую в конце предыдущего правила и текущего на всякий случай ;)

      Какие бывают уровни RAID массивов?

      Расскажите какие бывают уровни RAID массивов?

      RAID 0

      Raid 0 массив — Является конфигурацией массива без избыточности. Информация разбивается на блоки данных и записывается на несколько дисков одновременно. Отказ любого диска приводит к разрушению всего массива. Так как массив не является избыточным, процедура восстановления в случае выхода одного винчестера из строя, не предусмотрена. Надежность зависит от надежности каждого из дисков. Массив предназначен не для надежного хранения данных, а для повышения производительности.

      RAID 1

      Raid 1 массив — Зеркалирование данных, массив с избыточностью, где два диска полностью идентичны. Контроллер отвечает за одновременную запись на оба диска, обеспечивания тем самым "зеркалирование" информации для обеспечения избыточности. Выход из строя одного из них не ведет к потере данных. Данный вид обеспечивает высокую надежность хранения информации. При выходе и строя контроллера, данные можно считать подключив диск напрямую. Самый надежный вариант.

      RAID 5

      Raid 5 массив — Чередование с контролем четности. Чередование блоков данных происходит между тремя или более дисками. Все диски равноценны, а блоки четности разделены между ними. В таком случае при выходе из строя одного из них, данные не утрачиваются, и массив после перестроения (rebuild) может продолжать работу. Однако выход нескольких дисков из строя уже разрушит массив. Уровень 5 является одним из наиболее популярных реализаций RAID.
       

      RAID 6

      Raid 6 массив — Конфигурация очень похожа на RAID 5: в обеих используется чередование данных между жесткими дисками с распределенным блоком четности. Блок четности позволяет массиву реконструировать данные в случае отказа одного из жестких дисков. Однако RAID 6 использует функцию двойного контроля четности. Что позволяет выдержать отказ двух жестких дисков без потери данных.

      RAID 10

      Raid 10 массив — Это составная конфигурация, предоставляющая избыточность RAID 1 вместе с высокой скоростью записи и чтения RAID 0. Емкость массива составляет половину от общей емкости всех дисков, а массив требует минимум 4 диска. В каждом массиве данные чередуются между зеркалированными дисками, и таким образом, массив при отказе одного жесткого диска не произойдет потери данных.

      RAID 50

      Raid 50 массив — Фактически представляет собой массив RAID 0, состоящий из массивов конфигурации RAID 5. Они работают так же, как обычный RAID 5 массив, а это означает, собрать массив можно из минимум шести дисков. Емкость массива RAID 50 является суммой всех RAID 5 емкостей массива. Он характеризуется большей отказоустойчивостью и более высокой скоростью работы, чем пятый рейд.

      Как безопасно настроить подключение терминальных служб?

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

      Использование network-level authentication

      До появления Windows 2008/2008 R2, для аутентификации в службе терминалов пользователи должны были использовать Remote Desktop Client для установки связи с терминальным сервером. После чего у пользователя появлялась возможность ввода учетных данных  в окно входа. Такой подход к аутентификации пользователя выглядит довольно простым, в то же время с точки зрения безопасности является существенным риском.

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

      Начиная с Windows 2008, Microsoft вводит дополнительный уровень защиты - network-level authentication. Этот уровень предполагает, что пользователь представляет определенный набор данных до установки сеанса подключения, что делает процесс аутентификации более безопасным.

      Для использования network-level authentication необходимо выполнение ряда условий. Терминальный сервер должен работать под управлением операционной системы Windows 2008/2008 R2, а клиентские компьютеры должны  работать на ОС Windows XP Service Pack 3 или выше, Windows Vista или Windows 7. Для Windows XP может потребоваться редактирование реестра:

      1. Кликните "Пуск", "Выполнить", введите в строку "regedit" (без кавычек) и нажмите "Ok"

      2. В левой навигационной панеле откройте ключ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

      3. В правой панеле найдите параметр "Security Packages", нажмите на нём правой кнопкой мыши и выберите "изменить"

      4. В поле "значение" допишите внизу строчку "tspkg" (без кавычек). Не удаляйте имеющиеся значения. Нажмите "Ok"

      5. В левой навигационной панеле откройте ключ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders

      6. В правой панеле найдите параметр "SecurityProviders", нажмите на нём правой кнопкой мыши и выберите "изменить"

      7. В поле "значение" допишите через запятую строчку "credssp.dll" (без кавычек). Не удаляйте имеющиеся значения. Нажмите "Ok" 8. Перезагрузите компьютер

      Еще одним условием является использование Remote Desktop клиента версии 6 или выше.

      Существует несколько способов конфигурации терминального сервера на требование использовать network-level authentication. Вы можете включить Network Level Authentication в процессе установки роли Terminal Services, или после ее завершения, используя консоль Terminal Services Configuration. Щелкнув правой кнопкой мыши на подключении, используемом вашими клиентами. В меню выбрать  Properties и опцию "Allow connections only from computers running Remote Desktop with Network Level Authentication".

      Однако, наилучший способ включить network-level authentication, это использовать групповую политику.
      Запустите редактор групповой политики, выберите нужную политику. Откройте раздел Computer Configuration | Administrative Templates | Windows Components | Terminal Services | Terminal Server | Security и включите параметр Require user authentication for remote connections by using Network Level Authentication.

      Изменение номера порта RDP

      По умолчанию терминальный сервер использует порт 3389 для RDP подключения. Изменение номера порта RDP служит одним из самых эффективных способов защиты от хакеров.

      Смена номера порта требует внесения изменений в реестр. Настоятельно рекомендуется сделать резервную копию до внесения изменений.

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

      Запустите редактор реестра перейдите к ветке HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Terminal Server\WinStations\RDP-TCP.

      Внесите свое шестнадцатеричное значение в раздел Port Number.

      После того как вы внесли изменение в номер порта RDP на сервере, вам необходимо создать новое подключение на клиентском компьютере, используя новое значение порта RDP.  Для этого при настройке подключения необходимо указать порт, например 111.222.333.444:123456, где 111.222.333.444 – IP адрес сервера, 123456 – номер порта RDP.

      В заключении отметим, считается, что использование Windows Terminal Services относительно безопасно, есть возможность значительно повысить безопасность, используя описанные выше шаги.

      Источник: https://www.navus.kz/stati/microsoft/neskolko-prostich-shagov-dlya-bezop...

      Как понизить версию VM Hardware в VMWARE ESXI?

      Обновил ESXi сервер, и обновил версию виртуального оборудования, до новой версии. Теперь мне нужно мигрировать на другой сервер в котором старая версия сервера виртуальных машин. Как можно запустить страные машины с новым виртуальным оборудованием?

      При  откате/возврате к предыдущей версии ESXi на хосте виртуализации, в некоторых случаях может вызвать проблемы совместимости, одной из таких проблем является совместимость версии ESXi и используемой версии VM Hardware (виртуального аппаратного обеспечения ВМ). При попытке запуска виртуальной машина с более высокой версией VM Hardware на старой версии ESXi (которая не поддерживает новый формат оборудования), вы получите сообщение об ошибке и не сможете запустить ВМ.

      This virtual machine uses hardware version x, which is no longer supported. Upgrade is recommended.

      This virtual machine uses hardware version 13, which is no longer supported. Upgrade is recommended.

      Для решения таких проблем VMware предлагает три способа понижения версии аппаратного обеспечения виртуальной машины:

      • Возврат к снапшоту ВМ, сделанному до апгрейда (если апгрейд выполнен давно, вероятность долгосрочного хранения такого снимка небольшая)
      • Конвертация ВМ с помощью утилиты VMware vCenter Converter Standalone, в процессе которой можно выбрать требуемую версию виртуального «железа»
      • Создание новой ВМ с нужным уровнем совместимости VM Hardware и переподключения к ней диска vmdk имеющейся виртуальной машины

      В этом примере мы покажем процесс понижения версии VM Hardware с версии 13 до 11.

      Для начала, создадим новую виртуальную машину с помощью веб интерфейса vCenter (New Virtual Machine ).

      Создать новую виртуальную машину vcenter vmware

      Укажите, что вам нужна новая ВМ (Create a new virtual machine).

      Create a new virtual machine - vmware

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

      укажите имя ВМ

      Укажите хранилище, на котором будут расположен конфигурационный файл ВМ и ее диски.

      выбрать хранлилище для вм vmware

      На следующем шаге нужно будет указать уровень совместимости ВМ. В нашем случае нужно выбрать ESXi 6.0 and later, что означает использование 11 версии виртуального «железа».

      VM hardware версия ESXi 6.0 and later

      Выберите семейство и версию гостевой ОС.

      выбор типа гостевой ОС в виртулаьной машине

      Теперь нужно переподключить диск старой виртуальной машины к новой. Сначала нужно удалить автоматически созданный диск ВМ (New Hard disk), т.к. он нам не будет нужен.

      удаление пустого New Hard disk

      В выпадающем списке New Device выберите Existing Hard Disk и нажмите Add.

      Подключить имеющийся vmdk диск в Vmware Existing Hard Disk

      Вам будет предложено указать существующий vmdk файл. Найдите его на VMFS хранилище и нажмите OK. Если у старой ВМ было несколько дисков, нужно будет последовательно добавить их все.
      выбрать vmdk файлы

      На этом все, в окне создания ВМ можно нажать Finish.

      закончили создавать ВМ

      Будет создана новая машина с существующими дисками. Попробуйте включить ВМ и убедиться, что ОС загрузилась корректно, а версия vm hardware понизилсь.

       

      источник: https://vmblog.ru/kak-ponizit-versiyu-vm-hardware-virtualnogo-zheleza/

      Как в powerbi сделать отчет с разницей дат?

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

      Имеется набор данных следующего вида:

      • сотрудник;
      • дата приема на работу;
      • дата увольнения с работы;
      • признак того, что сотрудник работает в компании в настоящее время;
      • должность (позиция) сотрудника.

      art_008_screen_1

      Календарь выделен в качестве отдельной таблицы, при этом он создан “динамическим образом”, а именно:

      Calendar =
      CALENDAR ( FIRSTDATE ( 'Dataset'[Employment_Date] ); TODAY () )

      Задача:

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

      Решение:

      На уровне Power Query cоздано представление таблицы “Dataset”, при помощи контекстного меню “Reference” (“Ссылка”), имя представления задано как “Employee_dates”.

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

      pst.Dates ( [Employment_Date], 
      Duration.TotalDays( [Dismissal_Date] - [Employment_Date] ) + 1,
      #duration( 1, 0, 0, 0 ) )

      Один тонкий момент:

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

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

      art_008_screen_2

      На этом работы с Power Query завершены, далее необходимо настроить связи между данными:

      — связь одностороннего типа “Many to one” (“Многие к одному”) для Employee_dates -> Calendar;

      — связь двустороннего типа “Many to one” (“Многие к одному”) для Employee_dates -> Dataset.

      art_008_screen_3

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

      — общее количество персонала;

      — количество персонала, работающего в настояцее время;

      — количество персонала на определенной должности.

      Процесс визуализации данных:

      Создать несколько элементов “Card” (“Карточка”) для визуализации статистической информации по персоналу, используя соответствующие меры.

      Создать визуальный фильтр “Период”, используя элемент “Spcer” (“Срез”), при этом в качестве значений использовать данные столбца “Date” таблицы “Календарь”. При помощи данного элемента будет происходить процесс фильтрации дат с использованием двусторонней (!) связи”.

      Создать визуальный фильтр “Должность”, используя элемент “Spcer” (“Срез”), при этом в качестве значений использовать данные столбца “Position” таблицы “Dataset”. При помощи данного элемента будет происходить процесс фильтрации сотрудников согласно занимемой должности.

      создать таблицу “Список сотрудников”, используя элемент “Table” (“Таблица”), таблица является основным элементом отчета, и содержит полный список сотрудников.

      Исходя из нашего набора данных, в период с 01 января по 27 сентября 2019 года в компании было 12 сотрудников, 2 сотрудника занимали позицию Старшего менеджера, а 10 – Менеджера, и при этом в настоящий момент в компании работает 8 человек:

      art_008_screen_4

      Пояснения к отчету

      Если все сделано верно, то при изменении кочечного отрезка времени с “27.09.2019” на “12.02.2019” в таблице “Список сотрудников” должно отобразиться два сотрудника, поскольку ближайшая дата приема 3-го сотрудника – это “14.02.2019”, а подобное значение не должно учитываться в расчетах в соответствии с указанным периодом:

      art_008_screen_5

      То есть, по данным построенного отчета, в период с 14.01.2019 по 12.02.2019 в компании работало 2 человека на позиции Старшего менеджера, и при этом они оба продолжают работать в настоящий момент.

      Фильтр “Период” работает в обе стороны, и вернув конечную дату в значение “сегодня” (или более позднее), а затем изменив значение начального отрезка времени с “14.01.2019” на “01.06.2019”, в таблице “Список сотрудников” должно будет отобразиться 11 записей, поскольку один из сотрудников покинул компанию накануне (31.07.2019):

      Фильтрация данных при помощи дополнительных срезов (например, “Должность”), также производится корректным образом, поскольку, при нажатии кнопки “Менеджер”, таблица “Список сотрудников” отображает 9 записей, что соответствует значению меры “Менеджер, всего”, визуализированному при помощи элемента “Card” (“Карточка”).

      Источник: https://kkadikin.ru/ru/blog/article_008/

      Как узнать версию сборки ESXi с помощью Web Client?

      Здравствуйте!

      Как можно узнать какая весия esxi установлена на сервере?

      Узнать текущую версию и номер сборки севера ESXi с помощью веб клиента. После выпуска ESXi 6.5, старый толстый Windows клиент vSphere Client более не поддерживается и для управления ESXi и vSphere можно использовать только веб интерфейс клиента vSphere Web Client.

      Откройте Web Client и авторизуйтесь.

      Выберите свой хост ESXi и щелкните по вкладке Summary. Текущая версия сервера и номер сборки указаны в строке Hypervisor (выделено на скриншоте).

      В моем случае на сервере запушен ESXi 6.5, build 5310538.

      Источник: https://vmblog.ru/kak-uznat-versiyu-sborki-esxi-s-pomoshhyu-web-client-6-5/

      Как тестировать в Python сайты при помощи библиотеки Selenium?

      Скажите как пользоваться библиотекой Selenium в Python?

       

      Библиотека Selenium в Python предоставляет простой API для написания функциональных и интеграционных тестов веб-приложений. Благодаря Selenium Python API легко получить доступ ко всем функциям Selenium WebDriver интуитивным способом.

      Для работы Selenium требуется WebDriver. В настоящее время есть WebDriver для Firefox, Chrome, Edge и Safari. В примерах далее будет использован chromedriver.

      Установка Selenium

      Для установки пакета selenium воспользуемся программой pip. Установку рекомендуется проводить в виртуальном окружении Python.

      (venv) $ pip install selenium
      

      Установка chromedriver

      Процесс установки довольно прост, потому что chromedriver просто исполняемый файл в операционной системе, с которым Selenium будет взаимодействовать в процессе тестирования. Сверьтесь с официальной страницей chromedriver для загрузки и последующей установки свежей версии программы. Установка в Linux выглядит так :

      (venv) $ curl -L https://chromedriver.storage.googleapis.com/2.32/chromedriver_linux64.zip -o chromedriver.zip
      (venv) $ sudo unzip chromedriver.zip -d /usr/bin/
      (venv) $ sudo chmod +x /usr/bin/chromedriver
      

      Управление Chrome из Python

      Теперь импортируем пакет webdriver из selenium сказав ему использовать chromedriver.

      from selenium import webdriver
      
      driver = webdriver.Chrome()
      

      Выполнение этого кода приведёт к кратковременному появлению окна Chrome. Дальше ничего не будет происходить, потому что пример не сообщает webdriver никаких дополнительных инструкций.

      Решим простую задачу получения текущей версии программы учёта картриджей и принтеров в организации. Беглый взгляд на код главной страницы показывает, что версия находится внутри разметки:

      …
          <div class="large-4 medium-4 small-4 columns">
              <div class="callout">
                  <span class="date">20 декабря 2017 г.</span>
                  <p><a href="news/15">Релиз 1.8.0</a></p>
              </div>
          </div>
      …
      

      Таким образом, версия программы находится в тэге a внутри div с классом callout. Поиск его на странице показывает, что этот класс не уникален, поэтому используем Selenium для поиска первого элемента и получения его содержимого следующим образом:

      from selenium import webdriver
      
      driver = webdriver.Chrome()
      driver.get('https://www.severcart.org/')
      element = driver.find_elements_by_css_selector('.callout a')[0]
      print(element.text)
      driver.close()
      

      Запуск кода приведёт к вызову окна Chrome, которое загружает страницу целиком, затем производится поиск нужного результата с последующей его печатью в терминал. После выполнения скрипта производится закрытие окна браузера. В этом примере используется селектор CSS с Selenium методом find_elements_by_css_selector. Для навигации по страницам также доступно множество других методов find_element_by_ *.

      Скрытый запуск браузера

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

      from selenium import webdriver
      from selenium.webdriver.chrome.options import Options
      
      options = Options()
      options.add_argument('--headless')
      driver = webdriver.Chrome(chrome_options=options)
      driver.get('https://www.severcart.org/')
      element = driver.find_elements_by_css_selector('.callout a')[0]
      print(element.text)
      driver.close()
      

      Выполнение этого кода распечатает текст текущей версии, как и в предыдущем примере, но на этот раз не появится окно Chrome. Это связано с тем, что новая версия использует класс webdriver.chrome.options для передачи аргументов в бинарник Chrome с использованием chrome_options. Единственная опция которая здесь передается --headless, которая сообщает Chrome о выполнении действий без визуализации.

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

      Ключевые возможности selenium

      Существует множество важных классов и методов Selenium, которые будут широко использоваться для тестирования веб-страниц. Вот краткий список некоторых ключевых функций, о которых нужно знать. - Поиск элементов - Заполнение input - Очистка input - Ожидание

      Поиск элементов

      Всего восемь методов поиска (плюс ещё восемь во множественном числе):

      find_element_by_class_name
      find_element_by_css_selector
      find_element_by_id
      find_element_by_link_text
      find_element_by_name
      find_element_by_partial_link_text
      find_element_by_tag_name
      find_element_by_xpath
      

      Все эти методы довольно длинные, поэтому хорошим помощником является класс webdriver.common.By. By может заменить методы более длинной формы простым сокращением. Предыдущий пример кода можно заменить на:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      
      driver = webdriver.Chrome()
      driver.get('https://www.severcart.org/ ')
      element = driver.find_elements(By.CSS_SELECTOR, '.callout a')[0]
      print(element.text)
      driver.close()
      

      Хотя этот код не является кратким, поэтому предлагается его немного доработать создав метод обертки для поиска элементов. Это должно значительно сократить усилия по набору этих методов по мере увеличения размера теста и сложности. Вот примерная обёртка:

      def find(self, by, value):
          elements = self.driver.find_elements(by, value)
          if len(elements) is 1:
              return elements[0]
          else:
              return elements
      

      Используется множественный метод find_elements и возвращает либо список, либо один элемент в зависимости от того, сколько их найдено. При этом можно использовать find(By.ID, 'my-id'), вместо driver.find_element_by_id('my-id'). Эта форма преобразует код в гораздо более чистый, особенно при переходе между различными доступными методами поиска.

      Отправка Input

      Большинство проектов веб-приложений будут иметь дело с полями ввода, Selenium также это хорошо поддерживает. Каждый класс webelement (результат различных методов find_element) содержит метод send_keys, который может использоваться для моделирования ввода текста в элементе. Попробуем использовать эту функцию для поиска «Python» в Википедии.

      Быстрый просмотр источника страницы Википедии показывает, что элемент ввода поиска использует идентификатор searchInput.

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      
      driver = webdriver.Chrome()
      driver.get('https://www.wikipedia.org/')
      el = driver.find_element(By.ID, 'searchInput')
      el.send_keys('Python')
      

      Вышеприведенный код откроет окно Chrome с загруженной страницей в Википедии и «Python» в поле ввода поиска. Это окно остаются открытым, потому что код не включает команду driver.close(), которая используется в предыдущих примерах.

      Есть несколько вариантов отправить форму. Далее приведено несколько способов, которые позволяют это выполнить.

      Отправка содержимого формы

      Еще раз взглянув на html источник в Википедии, форма поиска содержит id=search-form. Далее идентификатор можно использовать с методом webelement.submit() для отправки формы.

      Добавьте в предыдущий пример следующий код:

      form = driver.find_element(By.ID, 'search-form')
      form.submit()
      

      Запуск кода приведёт к открытию окна Chrome с результатами поиска в Википедии слова Python.

      Нажатие кнопки submit формы

      Страница поиска Wikiedpia включает в себя причудливую, стилизованную кнопку отправки запроса поиска. У него нет уникального идентификатора, поэтому для определения и «щелчка» кнопки код должен использовать какой-либо другой метод. Это единственный элемент button внутри формы поиска, поэтому его можно легко выбрать с помощью селектора CSS.

      Добавьте в пример использования Input:

      button = driver.find_element(By.CSS_SELECTOR, '#search-form button')
      button.click()
      

      Нажатие клавиши ENTER

      В заключении, Selenium содержит набор кодов клавиш, которые могут использоваться для имитации нажатия «специальных» (не буквенно-цифровых) клавиш. Эти коды находятся в webdriver.common.keys. Чтобы отправить форму, код должен будет использовать клавишу Enter, поэтому пересмотренная версия поискового кода Википедии выглядит так:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.common.keys import Keys
      
      driver = webdriver.Chrome()
      driver.get('https://www.wikipedia.org/')
      el = driver.find_element(By.ID, 'searchInput')
      el.send_keys('Python')
      el.send_keys(Keys.RETURN)
      

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

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

      Очистка input

      Хотя Selenium предлагает метод webelement.clear(), его реализация несовместима в разных браузерах, и ее поведение может быть определено по-разному в зависимости от тестируемого приложения и элемента. По этим причинам не рекомендуется им пользоваться для очистки полей ввода формы. Вместо этого класс Keys может использоваться для имитации нажатия клавиши backspace несколько раз в input.

      Простая функция реализации.

      from selenium.webdriver.common.keys import Keys
      
      
      def clear(element):
          value = element.get_attribute('value')
          if len(value) > 0:
              for char in value:
                  element.send_keys(Keys.BACK_SPACE)
      

      Простая функция будет принимать WebElement, вычислять длину его атрибута value и имитировать нажатие BACK_SPACE, пока весь текст не будет удален из input.

      Давайте используем Selenium для поиска в Google слова «selenium». Элемент input поиска Google не имеет уникального идентификатора или класса, но он использует атрибут name со значением «q». Его можно использовать для поиска элемента и отправки keys.

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.common.keys import Keys
      
      
      def clear(element):
          value = element.get_attribute('value')
          if len(value) > 0:
              for char in value:
                  element.send_keys(Keys.BACK_SPACE)
      
      driver = webdriver.Chrome()
      driver.get('https://www.google.com/')
      el = driver.find_element(By.NAME, 'q')
      el.send_keys('selenium')
      el.send_keys(Keys.RETURN)
      

      На странице результатов поле поиска по-прежнему имеет значение «q» и теперь заполнено значением «selenium». Хотя имя не изменилось, Selenium нужно будет снова найти элемент, потому что страница изменилась. Добавьте в код изменения, чтобы найти элемент и использовать пользовательскую функцию clear() для его очистить:

      el = driver.find_element(By.NAME, 'q')
      clear(el)
      

      В целом BACK_SPACE должен быть намного надежнее, чем метод webelement.clear().

      Ожидание

      «Ожидание» в Selenium может быть обманчиво сложной проблемой. До сих пор все примеры основывались на способности Selenium дождаться, когда страница закончит загрузку, прежде чем предпринимать какие-либо конкретные действия. Для простых тестов это может быть вполне достаточным. Но по мере усложнения тестов и приложений этот метод может не всегда быть пригодным.

      Selenium предоставляет некоторые полезные инструменты для решения этой проблемы -

      Неявные ожидания Самый простой способ добавить вызов метода WebDriver.implicitly_wait (). Метод принимает целочисленный ввод, который определяет, сколько секунд ждать при выполнении любого из методов find_element.

      По умолчанию неявное ожидание равно нулю (или нет ожидания), поэтому, если конкретный элемент не найден сразу, Selenium будет вызывать исключение NoSuchElementException. Попробуем найти элемент name с атрибутом «query» на GitHub (его нет):

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.common.keys import Keys
      
      driver = webdriver.Chrome()
      driver.get('https://www.github.com/')
      el = driver.find_element(By.NAME, 'query')
      

      Этот код вызовет исключение NoSuchElementException после того, как Chrome загрузит домашнюю страницу GitHub.

      Теперь давайте проверим код ниже, который устанавливает неявное время ожидания в пять секунд для одной и той же невыполнимой задачи:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.common.keys import Keys
      
      driver = webdriver.Chrome()
      driver.implicitly_wait(5)
      driver.get('https://www.github.com/')
      el = driver.find_element(By.NAME, 'query')
      

      Этот код создаст то же самое исключение, но он будет ждать пять секунд, прежде чем это сделать.

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

      Рекомендуется всем тестам установку 10 секундного неявного времени ожидания. Это должно помочь предотвратить прерывистые исключения, вызванные проблемами с такими базовыми элементами, как сетевое подключение или баги веб-серверов.

      Ожидаемые условия (явные ожидания)

      Когда неявных ожиданий недостаточно, ожидаемые условия чрезвычайно ценны. Класс WebDriverWait предоставляет методы until() и until_not(), которые могут использоваться с ожидаемыми условиями для создания более сложных и нужных условий ожидания.

      presence_of_element_located() примет объект, описывающий метод и локатор, и вернет true, если объект существует в DOM. Это можно использовать с WebdriverWait.until () и временем ожидания (в секундах):

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebdriverWait
      from selenium.webdriver.support import expected_conditions as ec
      
      driver = webdriver.Chrome()
      WebdriverWait(driver, 5).until(ec.presence_of_element_located((By.ID, 'html-id')))
      

      Для чего нужен WebDriverWait? Кратко - одностраничные приложения (SPA). Тестирование может потребовать перемещения навигационных элементов приложения, и если страница не будет полностью перезагружена, Selenium должен будет использовать WebDriverWait, чтобы делать такие вещи, как ожидание загрузки нового раздела или таблицы данных после вызова API в стиле AJAX.

      Другие ожидаемые условия будут в значительной степени соответствовать одному и тому же синтаксису и в основном иметь (очень) подробные имена. Два из других, которые я нашел полезными на практике, - text_to_be_present_in_element() и element_to_be_clickable().

      Время ожидания

      Также используется метод обходного пути для простого, явного ожидания по времени без каких-либо ожидаемых условий. Одна из областей, где это может пригодиться - это тестирование результата «секундомера» на Javascript, который обновляется в реальном времени. В рамках теста я запускаю секундомер, подождите две секунды, а затем проверю, чтобы отображаемое время было правильным. Чтобы достичь этого, я создал метод, который по существу делает ожидаемое условное ожидание, которое умышленно уходит в прошлое:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebdriverWait
      
      def wait(self, seconds):
          try:
              WebdriverWait(self.driver, seconds).until(lambda driver: 1 == 0)
          except TimeoutException:
              pass
      

      Этот метод можно использовать, например, ждать пять секунд, вызвав wait (5). WebDriverWait вызовет исключение через пять секунд, потому что аргумент until () - простая лямбда, которая всегда будет возвращать False. Улавливая и передавая исключение, метод просто ожидаеи указанное количество секунд и ничего больше.

      Источник: https://www.severcart.ru/blog/all/python_selenium_testing/

      Как ввести большое число в ячейку таблицы?

      У меня есть список телефонов, ввожу номер в ячейку и она превращается в формулу. Как ввести номер телефона в Таблицу Google чтобы он остался номером телефона?

      Ввод формулы в Таблицу Google

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

      Суть на картинке

      Вместо строки вводится формула

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

      Апостроф в формуле

      Для представления числа в виде текста можно использовать формулу

      ="+" & A1
      =TEXT(A1;"+0 000 000 00 00")

      Для чисел можно задать формат

      +# ### ### ## ##

      Применение форматов

      Еще возможно просто добавить пробел перед "+"

       

      Источник: https://gdriveru.blogspot.com/2014/07/phonenumberincell.html

       

      Страницы

      Операционная система заметно «притормаживает»? Установленное программное обеспечение работает некорректно?

      Помните, что все действия вы выполняете на свой страх и риск — загрузка неверных данных может повлечь за собой крах системы и потерю информации.
      Тестирование в тестовой среде никто не отменяет.
      Администрация сайта не несет ответственность за ваши действия.
      Вся информация на сайте носит исключительно справочный характер и не является публичной офертой, определяемой в Статье 437 Гражданского кодекса Российской Федерации.