- Показать все активные подключения:
netstat
- Показать все активные подключения и ожидающие порты:
netstat -a
- Показать приложения (процессы), использующие активные подключения и прослушивающие порты:
netstat -a -b
(использование ключа-b
требует запуска от имени администратора): - То же самое — только вместо имени процесса — его PID —
netstat -o
либоnetstat -a -o
- Проверить, занят ли порт: `netstat -aon | findstr :9090`
- Отобразить все подключения со статусом listening: `netstat -a | find /I «listening»`
- Запись результата команды в файл: netstat -a > C:\netstatall.txt
- Показать все соединения и прослушиваемые порты по протоколу tcp: `netstat -a -p tcp`
- То же самое для udp — `netstat -a -p udp`, для icmp — `netstat -a -p icmp`
- Отображение полного имени домена
netstat -f
- netstat 3 — циклический запуск команды каждый 3 сек
Категория "Поддержка":
Центр поддержки клиентов
Что такое однобайтовая кодировка?
Когда мы читаем текст, нам кажется, что есть только один способ хранения текста в памяти — в виде букв (почему нет? :)). На самом деле существует множество кодировок, в которых текст может храниться и обрабатываться cpu. И далее я вкратце опишу самые распространенные из них:
ASCII
ASCII — это однобайтовая кодировка, где первые 128 символов — это управляющие символы (табы, переносы, символы заголовков. некоторые из них используются только в бинарных файлах) и латинские символы. После 128 символа могут быть символы «расширенного ASCII» (как например, Windows-1251, KOI8-R, CP866) — такие кодировки называют ASCII-совместимыми. Однако, в связи с тем, что представление классической ASCII (символы которой умещаются в 7 бит) может несколько отличаться при отображении в памяти при отсутствии расширяемых символом, то даже для латыни требуется специальная конвертация для перевода из ASCII кодировки в расширенную и наоборот.
Интересное: CP-866 — это дефолтная кодировка консоли в Windows.
UNICODE
Unicode — это другая кодировка, которая появилась после ASCII. Коды в стандарте Юникод разделены на несколько областей. Область с кодами от U+0000 до U+007F содержит символы набора ASCII, и коды этих символов совпадают с их кодами в ASCII. Далее расположены области символов других систем письменности.
Первая версия Юникода (1991 г.) представляла собой 16-битную кодировку с фиксированной шириной символа; общее число разных символов было 216 (65 536). Сейчас же юникод имеет несколько форм представления: UTF-8, UTF-16 (UTF-16BE, UTF-16LE) и UTF-32 (UTF-32BE, UTF-32LE), где размер 1 символа может варьироваться.
UTF-8
UTF-8 — представление Юникода, обеспечивающее наибольшую компактность и обратную совместимость с 7-битной системой ASCII; текст, состоящий только из символов с номерами меньше 128, при записи в UTF-8 превращается в обычный текст ASCII и может быть отображён любой программой, работающей с ASCII; и наоборот, текст, закодированный 7-битной ASCII может быть отображён программой, предназначенной для работы с UTF-8. Остальные символы Юникода изображаются последовательностями длиной от 2 до 4 байт, в которых первый байт всегда имеет маску 11xxxxxx
, а остальные — 10xxxxxx
. В UTF-8 не используются суррогатные пары. Итого размер симола utf8 варьируется от 1 до 4 байт (то есть 1, 2, 3 или 4 байт). Является сегодня де-факто стандартом в web.
UTF-16
В UTF-16 символы кодируются двухбайтовыми словами с использованием всех возможных диапазонов значений (от 0 до FFFF16). При этом можно кодировать символы Unicode в диапазонах 000016..D7FF16 и E00016..10FFFF16. Исключенный отсюда диапазон D80016..DFFF16 используется как раз для кодирования так называемых суррогатных пар — символов, которые кодируются двумя 16-битными словами. Итого в UTF-16 занимает либо 2 либо 4 байта. Является базовой кодировкой в .NET.
UTF-32
UTF-32 — способ представления Юникода, при котором каждый символ занимает ровно 4 байта. Главное преимущество UTF-32 перед кодировками переменной длины заключается в том, что символы Юникод в ней непосредственно индексируемы, поэтому найти символ по номеру его позиции в файле можно чрезвычайно быстро, и получение любого символа n-й позиции при этом является операцией, занимающей всегда одинаковое время. Это также делает замену символов в строках UTF-32 очень простой. Напротив, кодировки с переменной длиной требуют последовательного доступа к символу n-й позиции, что может быть очень затратной по времени операцией. Главный недостаток UTF-32 — это неэффективное использование пространства, так как для хранения любого символа используется четыре байта. Используется python для Linux систем.
UTF-7
UTF-7 — довольно интересный формат, не водящий в спецификацию Unicode. Дословано — 7-bit Unicode Transformation Format — «формат преобразования Юникода, 7 бит». Разработан как альтернатива base64 для кодирования управляемых символов, знаков препинания и прочих символов за пределами ascii. В основном используется для передачи сообщений в электронной почте. Хотя MIME позволяет кодировать тело сообщения из разных наборов символов (более широких, чем ASCII), базовая инфраструктура передачи (SMTP, основной стандарт передачи E-mail) по-прежнему не гарантирует 8-битную чистоту. В отличие от base64, которая кодирует каждый байт отдельно, UTF-7 кодирует непосредственно юникод символы. UTF-7 стало хорошей альтернативой для base64 в плане чтения записи, поскольку позволяет быстрее кодировать и декодировать различные формы представления юникод, нежели base64, однако один символ может занимать от 6 до 12 байт.
Итак, теперь вы познакомились с наиболее популярными кодировками. Знание их отличительных особенностей пригодятся в любой сфере программирования. И если хотите — эту статью можете добавить себе в закладки :). Я не против.
Настройка babel на Windows10
В прошлой статье мы разобрали, как настроить less в gulp под Windows. В этой мы поговорим о настройке babel компилятора — транпайлера для javascript, позволяющего писать код на js в стиле ES6, под старые браузеры.
Будем считать, что вы уже выполнили пункты из предыдущей статьи, открываем папку проекта. Переходим в его корень. В моем случае в папку cd D:\_virtualenv_main & D:
. Продолжить чтение
Настройка gulp-less под Windows
В этой статье шпаргалке пойдет речь, как быстро развернуть gulp-less под Windows. Мы опустим тему о том, что это такое и для чего нужно, и будем считать, что читатель уже знаком с понятием css-препроцессора.
Итак, первое, с чего необходимо начать это
- Установить node.js, если он не установлен. Для этого идем на оффициальный сайт и качаем последнюю версию node под вашу версию операционной системы. Дожидаемся скачивания, запускаем установку, следуем инструкциям, соглашаясь со всеми пунктами. После установки в терминале должна работать команда
node
: - Теперь нужно создать проект: запускаем консоль, переходим в папку с проектом через
cd path
и набираем в терминалеnpm init
. При создании проекта у нас будетзапрошено его название и прочая информация — ее можно оставить по дефолту. Жмем несколько раз Enter до подтверждения и подтверждаем: - Проект создан. В указанной папке должен появиться файл
package.json
со следующим содержимым:{ "name": "myproject", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
Теперь в него необходимо установить пакеты. На начальном этапе нам нужно всего лишь два пакета:
gulp и gulp-less. В той же консоли вводим команду:npm install gulp --save-dev
И затем
npm install gulp-less --save-dev
И ждем завершения установки. После завершения установки в
package.json
должны появиться следующие записи:{ "name": "myproject", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC", "devDependencies": { "gulp-less": "^4.0.1", "gulp": "^4.0.2" }, }
Вышеуказанные пакеты можно ставить и без ключа —save-dev. Это не играет роли, если вы не собираетесь выкладывать свой пакет в пакетный менеджер npm.
- Теперь необходимо создать скрипт, который будет выполнять gulp. По традиции он называется
gulpfile.js
и находится в корне той же директории, что иpackage.json
. Т.к. это — шпора, а не учебник, я опущу подробности и сразу укажу работающий скрипт для less:var gulp = require('gulp'); var less = require('gulp-less');// подключаем gulp-less const src_path = 'django_test/main/static/**/*.less'; gulp.task('less', function(){ return gulp.src(src_path) .pipe(less({})) .pipe(gulp.dest('django_test/main/static/')) }); gulp.task('watch', function(){ return gulp.watch(src_path, gulp.series('less')); }); //*/ gulp.task('default', gulp.series('less', 'watch'));
Параметры для методов gulp.src и gulp.dest от проекта к проекту, конечно же, будут отличаться. Полагаю, вы разберетесь.
- При установке пакетов особо внимательные пользователи могли заметить, что помимо изменения содержимого файла package, в папке проекта также появилась директория
node_modules
, которая содержит весь код скачанных пакетов. А так же папка.bin
, содержащая alias-ы для их запуска. Заходим туда черезcd node_modules/.bin
, набираемgulp.cmd
и наслаждаемся результатом
Аналогичного результата можно достичь более быстрым способом, если прописать в scripts
вашего package.json
код для запуска gulp: "start": "node \"./node_modules/gulp/bin/gulp.js\""
. Тогда мы сможем запускать ее из любого места нашего проекта командой npm run start
. Для запуска конкретного такса нужно просто задать его имя, например:
npm run start "less"
Многие так же рекомендуют ставить gulp глобально (с ключом -g): npm i -g gulp
. Это позволяет запускать команды gulp еще более изящно:
gulp
Либо конкретный таск
gulp less
Post Scriptum
Результат, достигаемый этим скриптом, достижим и с помощью программного комплекса Koala без всяких лишних заморочек: установок пакетов в командной строке, написания скриптов и прочего. Koala очень удобна, интуитивно понятна, бесплатна, нетребовательна к ресурсам и навыкам, благодаря эргономичному графическому интерфейсу. И если описанная выше технология вам покажется сложной, можете попробовать ее.Я считаю, что koala вполне достаточно, чтобы настроить дефолтное рабочее место верстальщика. Gulp же нужен, когда вы хотите кастомизировать это место и эта кастомизация выходит за рамки возможностей коалы.
Однако для фронтэнд-разработки вам может не хватить и gulp-а. Тогда вам понадобятся бандлеры. Сегодня наиболее популярным (но не лучшим, по мнению автора) является webpack.
Но этом пока все. Всем удачи 🙂
Шпаргалка по грамотной верстке
Если вы начинающий верстальщик, то эта шпаргалка поможет вам ориентироваться в этом непростом и местами запутанном мире.
Первый вопрос, который возникает у любого true-верстальщика — это как построить скелет сайта так, чтобы он работал во всех браузеров без бесконечной переделки. И мы не исключение :).
Для начала необходимо определиться, какие браузеры мы хотим поддерживать поддерживать. В современном мире верстки бытует мнение, что поддерживать старые браузеры — не модно. И я оставлю адептов моды при их мнении.
Если вы возьмете топ-компании наподобие Яндекса, то увидите, что их главная страница готова валидно открыться даже на ie5, которому — на минуточку — уже более 20 лет! Это говорит о том, что если вы разрабатываете солидный сайт, который будет рассчитан на все слои населения, то одним из приоритетов должно стать поддержка как можно бОльшего спектра браузеров… Однако мы не будем бросаться в такие крайности. Всегда стоит исходить не из амбиций, но и целесообразности. Вряд ли вы собираетесь запустить второй яндекс. Но тем не менее поддержка браузеров, которые помнит нынешнее поколение, еще, вероятно, нуждаются в вашей поддержке:
- Если ваш сайт нуждается в поддержке IE8+, то для верстки нужно использовать
%
иem
там, где это возможно. И только для минорных элементов —px
. Для горизонтальных меню и колонок использовать элементы сdisplay: inline-block
. Если по каким-то причинам `inline`-блоки не справляются, для создания скелета можно использовать абсолютное позиционирование, но с оглядкой на transform.
- Для IE9+ появилась возможность использовать специальный метод
calc
, позволяющий смешивать несколько единиц измерения, а так жеvh/vm
,rem
. И для создания скелета лучшеcalc
на данном этапе придумать сложно. Преимущество vh/vw над % в том, что % не может быть применен к элементу, родитель которого, не имеет фиксированной высоты или ширины, а `vh/vw` — может. Аrem
позволяет не обращать внимание на переопределение размера шрифта внутри элементов и верстать всю страницу в едином стиле. Использование единиц внутри calc —vh/vw
,rem
и единицы из предыдущего пункта.
- Для IE10+ появились такая хорошая вещь, как flex. Теперь для позиционирования горизонтальных меню можно забыть об
inline-block
.Flex
во многом упрощает верстку, так вертикальное выравнивание внутри элементов. Поэтому там, где это возможно, лучше использовать именно его. Если нет, см. предыдущие пункты.
На этом краткий ликбез закончен. Смотрите примеры на нашем codepen.io.
Сравнение производительности .NET и node.js
Код для тестов:
C#:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static int Test(){ var sum = 0; for(var i=0;i<10000000;i++){ sum+=2; } return sum; } static void Main(string[] args) { Applay(); Applay(); if (Console.ReadKey().Key == ConsoleKey.A) Main(new string[]{}); } private static void Applay() { var sw = System.Diagnostics.Stopwatch.StartNew(); Console.WriteLine(Test()); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } } }
node.js:
const performance = require('perf_hooks').performance; function Test(){ var sum = 0; for(var i=0;i<10000000;i++){ sum+=2; } return sum; } function apply(){ var time = performance.now(); console.log(Test()); time = performance.now()- time; console.log('Время выполнения 1 = ', time); } for (var a=0;a<5;a++){ apply(); }
Система Win7 x32 с предустановленным фреймворком .NET 4.6.1 и node.js 12.2. Результаты:
Итого: node.js уступил немного .NET во времени компиляции, буквально на несколько процентов, и после JIT-компиляции обогнал его почти в 2 раза! Но не спешите с выводами! Тк это неверный бенчмарк? Да. В этом бенчмарке .NET был запущен в Debug режиме. При Realese средняя скорость на .NET составила всего 0.13 мс, так что .NET побеждает. Однако, V8 меня удивил, ибо я ожидал отставания раз в 10 минимум, если не в 100.
Поехали дальше. Попробуем вычислить синус большого числа (бредовое задание, но пусть для проверки):
C#
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static double Test() { double sum = 0; for (long i = 0; i < 10000000000; i++) { Math.Sin(i); } return sum; } static void Main(string[] args) { Console.ReadLine(); for (int i = 0; i < 5; i++) { Applay(); } Console.ReadKey(); //if (Console.ReadKey().Key == ConsoleKey.A) Main(new string[] { }); } private static void Applay() { var sw = System.Diagnostics.Stopwatch.StartNew(); Test(); //Console.WriteLine(Test()); sw.Stop(); Console.WriteLine(sw.ElapsedMilliseconds); } } }
node.js:
const performance = require('perf_hooks').performance; function Test(){ //var sum = 0; for(var i=0;i<10000000000;i++){ Math.sin(i) } //return sum; } function apply(){ var time = performance.now(); console.log(Test()); time = performance.now()- time; console.log('Время выполнения 1 = ', time); } for (var a=0;a<5;a++){ apply(); }
Результаты:
Здесь тестировался Realese режим C#, тк в Debug время превышало в 20 раз Realese, и я не вижу смысла его приводить. Какие в нем могут быть ошибки? В node можно поставить let вместо var. Вы правы, и я сделал это сразу после того, как заметил. И… результат оказался лучше предыдущего. Судите сами:
Но я бы не сказал однозначно, что он лучше, чем у .NET: только один вызов из пяти оказался быстрее, что похоже на погрешность, и если взять среднее время, то в целом .NET выигрывает около 10-ти процентов процентов и здесь.
Что еще можно. Забыл убрать console.log, который выполняется аж 5 раз. Убрал, и заменил просто на вызов Test()
. Ничего не поменялось (кстати, даже хуже результат — видимо, погрешность оказалась сильнее разницы :)).
Почему ж второй результат у node.js оказался лучше, чем первый, и дышал шарпу почти в затылок? Потому что в js все числа, тип Number, по дефолту представляют из себя 64-битное число с плавающей точкой. и на данный момент там нет возможности управлять типами чисел. Шарп же позволяет оптимизировать свой код, благодаря статической более точной типизации. В остальном можно сказать, что несмотря на небольшую разницу (кстати, если поменять цикл for на while, то результат будет лучше у node, но в среднем не более, чем на 1 мс и хуже, чем аналогичный результат с for на 3мс), оба JIT-компилятора имеют примерно равную очень высокую производительность по работе с числами.
Но несмотря на близость результатов .NET на данный момент, благодаря возможностям более тонкой настройке, позволяет писать более производительные приложения, чем node.js.
Но числа — это не самое главное. Сделаем элементарный тест по работе со строкой:
const performance = require('perf_hooks').performance; function Test(){ let s = "str"; for(let i=0;i<100000;i++){ s.replace('t',''); } } function apply(){ var time = performance.now(); //console.log(Test()); Test(); time = performance.now()- time; console.log('Время выполнения ' + a + ' = ', time); } for (var a=0;a<5;a++){ apply(a); }
Против:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static string Test() { string s = "str"; for(int i=0;i<100000;i++) { s.Replace("t", ""); } return s; } static void Main(string[] args) { Console.ReadLine(); for (int i = 0; i < 5; i++) { Applay(i); } Console.ReadKey(); //if (Console.ReadKey().Key == ConsoleKey.A) Main(new string[] { }); } private static void Applay(int i) { var sw = System.Diagnostics.Stopwatch.StartNew(); Test(); sw.Stop(); Console.WriteLine("Время выполнения " + i + ": " + sw.ElapsedMilliseconds); } } }
Максимальное время выполнения на .NET: 15мс, на node — 47мс. Минимальное на .NET — 13 мс, на node — 37мс.
PS Кстати, решил проверить python на последнем тесте- он традиционно хуже в математике по сравнению с .NET примерно в 1000 раз, но удивительно, что при replace он не уступил ноде (39-41мс):
def main(): s = 'str' for i in range(100000): s.replace('t','') if __name__ == '__main__': import time for i in range(5): start = time.time() main() end = time.time() print(end - start)
Делаем выводы.
Трюки и лайфхаки git
Подключение к репозиториям
git remote
— показать имена всех удаленных репозиториев
git remote -v
— показать все удаленные репозитории
git remote rm [name]
— удалить назначенный удаленный репозиторий
Регистрация изменений
git status
— показать незарегистрированные изменения
git log --oneline [-n 5]
— краткий просмотр коммитов
git log
— просмотр коммитов подробный Продолжить чтение
Kivy-элементы
Основные элементы kivy:
Layout — слои
from kivy.uix.boxlayout import BoxLayout— слой, позволяющий размещать элементы блоками с вертикальной либо горизонтальной ориентацией (`orientation=vertical`). Элементы размещаются последовательно и не перекрывают друг друга. По умолчанию, ориентированы слева направо.
from kivy.uix.stacklayout import StackLayout — слой, позволяющий размещать элементы встраиваемыми блоками последовательно согласно одной из восьми ориентаций. Элементы так же размещаются последовательно и не перекрывают друг друга. По умолчанию ориентированы сверху вниз.
from kivy.uix.floatlayout import FloatLayout — задает положение элементов через абсолютное (pos=(20, 20)
) либо относительное (pos_hint={'x':0, 'y':.8}
) позиционирование каждого элемента. Понятия ориентации не существует. Элементы могут перекрывать друг друга и выходить за пределы экрана.
Работа с удаленными репозиториями github через git bash
Итак, первое, что необходимо сделать, чтобы работать с гит через консоль из под Windows, это скачать и установить git bash. Все настройки советую оставлять по умолчанию.
Итак, вы установили git bash и у имеете [удаленный репозиторий на github и] учетную запись, созданную через веб-интерфейс сайта github.com. Запускаем git bush и переходим в папку, в которой будет храниться/уже хранится наш локальный репозиторий. В дальнейшем, чтобы минимизировать выполняемые действия, советую создать небольшой скрипт вида:
cd путь_к_проекту; "%programfiles%\Git\git-bash.exe"
В моем случае это
D: & cd D:\_github\django_test & "C:\Program Files\Git\git-bash.exe"
Который автоматически будет запускать git-bash в корне проекта.
Теперь нужно сказать, что github предоставляет два варианта взаимодействия с сервером: https и ssh. Ниже мы рассмотрим их более детально в трех вариантах развития событий. И первый вариант развития:
1. Новый репозиторий
Вы только что создали репозиторий на гитхаб и собираетесь выложить туда готовый проект
Для начала необходимо подготовить локальный репозиторий. Для этого вводим команды:
git init git config --global user.name 'Sanshain' git config --global user.email 'my-email@ya.ru' git add . git commit -m "first commit"
Первой командой (git init
) мы инициализировали новый репозиторий. Команда git add .
проиндексировала все файлы внутри текущей директории, а командой git commit -m "first commit"
мы сделали первый commit (фиксацию изменений). Все, ура. Но пока промежуточное. Теперь нужно правильно выложить это все на гитхаб:
Для этого необходимо выполнить команду
git remote add origin <адрес нашего репозитория на гитхаб>
- https (например,
https://github.com/Sanshain/django_test.git
либоhttps://Sanshain@bitbucket.org/Sanshain/obfuscatenet.git
для bitbucket) - ssh (например,
git@github.com:Sanshain/django_test.git
)
git push -u origin master
Нужно всего лишь ввести свои учетные записи (логин/пароль) в падающем окошке от гитхаб. И все файлы будут экспортированы в удаленный репозиторий.
Для второго же случая вам необходимо будет сгенерировать открытый и закрытый ключи у себя на пк. Для это выполните следующие команды:
ssh-keygen -t rsa -b 4096 -C "<имя учетной записи>" eval $(ssh-agent -s) ssh-add "<желаемый путь, куда будет сгенерирован ключ>"
ssh-add -l
. Теперь необходимо скопировать содержимое публичного ключа и создать новый ключ с этим содержимым в настройках личного кабинета гитхаб. После всего вышепроделанного можно выгружать локальный репозиторий git push -u origin master
. Сложно? На вкус и цвет…
2. Удаленный репозиторий
У вас уже есть репозиторий с вашим проектом на гитхаб, и нужно его синхронизировать с новым локальным репозиторием на пк. Переходим в папку, где будет храниться наш /репозиторий/проект (у меня это D: & cd D:\_github\
)
Для примера возьму свой репозиторий https://github.com/Sanshain/django_test.
Для клонирования существующего репозитория по https пишем:
git clone https://github.com/Sanshain/django_test.git
Результат команды должен выглядеть примерно следующим образом:
Cloning into 'django_test'... remote: Enumerating objects: 200, done. remote: Counting objects: 100% (200/200), done. remote: Compressing objects: 100% (170/170), done. remote: Total 200 (delta 19), reused 200 (delta 19), pack-reused 0 Receiving objects: 100% (200/200), 8.09 MiB | 582.00 KiB/s, done. Resolving deltas: 100% (19/19), done.
Теперь внутри нашей папки мы увидим новую папку, содержащую все файлы и папки нашего (или не нашего открытого) удаленного репозитория. Для дальнейшей работы с этой папкой через git bash
переходим в нее командой cd django_test
Теперь нужно учесть, что месторасположение файла в системе может отличаться от исходного, поэтому при запуске, вероятно, вы можете увидеть ошибки. А потому и конфигурацию нужно настраивать самостоятельно. Для того, чтобы это не делать каждый раз, в удаленном репозитории необходимо правильно настроить .gitignore
, специальный файл исключений, который поможет отключить из скв файл конфигурации. В моем случае это файл — manage.py
.
Создается .gitignore
с помощью команды touch .gitignore
либо сразу с содержимым — echo 'manage.py' > .gitignore
.
Если у вас python, советую добавить туда pyc-файлы строкой `*.pyc`.
Однако это не все… Если ‘manage.py’ уже проиндексирован, то необходимо его удалить [из индекса], сделать коммит и затем снова добавить (не забудьте скопировать перед выполнением):
git rm путь/к/файлу [-f] git commit -m ".gitignore added"
И добавляем обратно. Пишем еще какие-то изменения.
Если в процессе изменений были добавлены новые файлы, делаем git add .
.
Теперь можно коммитить на удаленный репозиторий наши изменения. Сперва проверяем удаленные репозитории:
git remote -v
Если пусто, то задаем. Есть два варианта подключения к удаленным репозиториям:
git remote add origin https://github.com/Sanshain/django_test.git
— первый запросит у нас логин/пароль от аккаунта
git remote add origin git@github.com:Sanshain/django_test.git
— второй потребует создание публичного ключа шифрования для гитхаб
Если удаленные репозитории уже заданы, делаем git push origin master
(если репозиторий уже отpushен с другого локального репозитория, то сперва необходимо выполнить git pull origin master
)
3. Общий репозиторий
И теперь рассмотрим самый коронный случай: у нас есть общий удаленный репозиторий и два локальных репозитория на разных компах, при чем оба репозитория могут коммитить файлы независимо друг от друга. Пример:
Вася сделал коммит со своего компа на удаленный репозиторий и ушел домой, но Петя остался на работе и продолжил править файлы, и сделал коммит на удаленный позже Васи. Вася на следующий день придет и уже не сможет продолжить работу со своим локальным репозиторием без угрозы потери изменений, которые делал Петя в его отсутствие в глобальный репозиторий, поскольку если он продолжит работу со своим локальным репозиторием и ‘отpush
ит’ его в глобальный, то попросту рискует их затереть. Поэтому ему необходимо сделать так называемый pull.
Команда pull объединяет в себе две команды — fetch (скачивает изменения) и merge (делает слияние). Выглядит она вот так:
git pull <название удаленного репозитория>
В моем случае это выглядит вот так:
git pull https://github.com/Sanshain/django_test.git
Если же Вася перед push уже успел внести какие-либо правки до выполнения команды pull
, то при ее выполнении он может столкнуться с конфликтами. Конфликты бывают разной степени «тяжести».
Я сейчас рассмотрю самый простой вид разрешения — это выбор заменяющего файла целиком, а не его фрагмента (поскольку последнее, на мой взгляд заслуживает отдельной статьи). Для того, чтобы оставить в локальной ветке локальную версию файла, необходимо выполнить команду
git checkout --ours <название файла>
Например:
git checkout --ours db.sqlite3
Если же нужно, чтобы файл целиком подменился его глобальной версией, вместо outer
необходимо использовать параметр theirs
.
Далее выполнить `git add -u` и git commit -m 'merge'
.
На этом пожалуй, все. Продолжение следует…
RecycleView
Recyclerview предоставляет гибкую модель для просмотра выбранных разделов больших наборов данных. Он направлен на предотвращение снижения производительности, которое может произойти при создании большого количества виджетов для отображения многих элементов данных.
Представление создается путем обработки данных, а именно — списка словарей, и использует эти словари для создания экземпляров класса View по мере необходимости. Его дизайн основан на шаблоне MVC (Model-view-controller).
- Модель: модель формируется данными, которые вы передаете через список словарей
- Представление: представление разделено на макеты (layers) и представлениям (Views) и реализовано с помощью адаптеров
- Контроллер: контроллер определяет логическое взаимодействие и реализуется поведением Recyclerview
Это абстрактные классы, которые нельзя использовать напрямую. Конкретные реализации по умолчанию — это модель данных Recycle для модели, макет Recycle для представления и RecycleView для контроллера.
При создании экземпляра Recyclerview он автоматически создает представления и классы данных. Однако необходимо вручную создать классы компоновки и добавить их в Recyclerview.
Менеджер макетов автоматически создается как layout_manager при добавлении в качестве дочернего объекта Recyclerview. Аналогично при удалении. Требование заключается в том, что менеджер макетов должен содержаться как дочерний элемент где-то в дереве виджетов Recyclerview, чтобы можно было найти порт представления.
Минимальный пример может выглядеть примерно так:
from kivy.app import App from kivy.lang import Builder from kivy.uix.recycleview import RecycleView Builder.load_string(''' <RV>: viewclass: 'Label' RecycleBoxLayout: default_size: None, dp(56) default_size_hint: 1, None size_hint_y: None height: self.minimum_height orientation: 'vertical' ''') class RV(RecycleView): def __init__(self, **kwargs): super(RV, self).__init__(**kwargs) self.data = [{'text': str(x)} for x in range(100)] class TestApp(App): def build(self): return RV() if __name__ == '__main__': TestApp().run()
Для поддержки выбора в представлении можно добавить необходимые режимы следующим образом:
from kivy.app import App from kivy.lang import Builder from kivy.uix.recycleview import RecycleView from kivy.uix.recycleview.views import RecycleDataViewBehavior from kivy.uix.label import Label from kivy.properties import BooleanProperty from kivy.uix.recycleboxlayout import RecycleBoxLayout from kivy.uix.behaviors import FocusBehavior from kivy.uix.recycleview.layout import LayoutSelectionBehavior Builder.load_string(''' <SelectableLabel>: # Draw a background to indicate selection canvas.before: Color: rgba: (.0, 0.9, .1, .3) if self.selected else (0, 0, 0, 1) Rectangle: pos: self.pos size: self.size <RV>: viewclass: 'SelectableLabel' SelectableRecycleBoxLayout: default_size: None, dp(56) default_size_hint: 1, None size_hint_y: None height: self.minimum_height orientation: 'vertical' multiselect: True touch_multiselect: True ''') class SelectableRecycleBoxLayout(FocusBehavior, LayoutSelectionBehavior, RecycleBoxLayout): ''' Adds selection and focus behaviour to the view. ''' class SelectableLabel(RecycleDataViewBehavior, Label): ''' Add selection support to the Label ''' index = None selected = BooleanProperty(False) selectable = BooleanProperty(True) def refresh_view_attrs(self, rv, index, data): ''' Catch and handle the view changes ''' self.index = index return super(SelectableLabel, self).refresh_view_attrs( rv, index, data) def on_touch_down(self, touch): ''' Add selection on touch down ''' if super(SelectableLabel, self).on_touch_down(touch): return True if self.collide_point(*touch.pos) and self.selectable: return self.parent.select_with_touch(self.index, touch) def apply_selection(self, rv, index, is_selected): ''' Respond to the selection of items in the view. ''' self.selected = is_selected if is_selected: print("selection changed to {0}".format(rv.data[index])) else: print("selection removed for {0}".format(rv.data[index])) class RV(RecycleView): def __init__(self, **kwargs): super(RV, self).__init__(**kwargs) self.data = [{'text': str(x)} for x in range(100)] class TestApp(App): def build(self): return RV() if __name__ == '__main__': TestApp().run()
Пожалуйста, смотрите examples/widgets/recycleview/basic_data.py файл для более полного примера.
Внимание: When views are re-used they may not trigger if the data remains the same.
API
class kivy.uix.recycleview.
RecycleViewBehavior
(**kwargs)
Основан на `builtins.object`
Поведение Recyclerview предоставляет поведенческую модель, на основе которой строится Recyclerview. Вместе они предлагают расширяемый и гибкий способ создания представлений с ограниченными окнами над большими наборами данных.
- data_model
- Модель данных, ответственная за поддержание набора данных.
- layout_manager
- Менеджер макетов, ответственный за размещение (позиционирование) видов в Recyclerview.
- refresh_from_data
- Это должно вызываться при изменении данных. Изменения данных обычно указывают на то, что все должно быть пересчитано с момента изменения исходных данных.
Этот метод автоматически привязывается к методу on_data_changed класса поведения модели данных Recycle и поэтому отвечает и принимает аргументы ключевого слова этого события.
Его можно вызвать вручную для запуска обновления.
- refresh_from_layout
- Это должно быть вызвано, когда макет изменяется или нуждается в изменении. Он обычно вызывается, когда параметр макета изменился,и поэтому макет должен быть пересчитан.
- refresh_from_viewport
- Это должно быть вызвано, когда видовой экран изменяется и отображаемые данные должны быть обновлены. Ни данные, ни макет не будут пересчитаны.
- view_adapter
- Адаптер, ответственный за предоставление представлений, представляющих элементы в наборе данных.
class kivy.uix.recycleview.
RecycleView
(**kwargs)
Основан на: kivy.uix.recycleview.RecycleViewBehavior
, kivy.uix.scrollview.ScrollView
Recyclerview — это гибкий вид для предоставления ограниченного окна в большой набор данных.
- add_widget
- Добавляет новый виджет в качестве дочернего элемента
- data
- Данные, используемые текущим адаптером представления. Это список dict, ключи которого сопоставляются с соответствующими именами свойств класса представления.
- key_viewclass
- key_viewclass is an AliasProperty that gets and sets the key viewclass for the current layout_manager.
- viewclass
- Класс представления, используемый текущим layout_manager. Возвращает и задает класс, используемый для создания отдельных элементов, представленных в представлении.