Страницы

Поиск по вопросам

понедельник, 9 декабря 2019 г.

Как проверить доступ к интернету?

#android


Подскажите, как проверить доступность интернет соединения? Именно доступность, бывают
ситуации когда интернет включен но не дает трафик(к примеру при нулевом балансе на счету)

Или проще самому делать проверку на подключение к серверу мол, если интернет включен
и сервер отвечает то всё нормально но, если интернет включен но сервер молчит значит
нет доступа к интернету?
    


Ответы

Ответ 1



Создайте метод: public boolean isOnline() { Runtime runtime = Runtime.getRuntime(); int exitValue = -1; try { Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8"); exitValue = ipProcess.waitFor(); } catch (IOException | InterruptedException ignored) {} ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); return netInfo != null && exitValue == 0 && netInfo.isConnectedOrConnecting(); } Разрешение в манифесте: Пример: if(isOnline) //если интернет есть else //если нет

Разбиение строк в формате с фиксированной шириной полей и необязательными значениями

#python #python_3x #регулярные_выражения #строки #python_2x


Есть большой массив данных. 

Пример строки из массива: 

20046 2005  27.0  44.3   9.0  15.9   3.6   9.2   9.2  37.5  18.3  18.6  24.4  26.0


Где первые два значения - номер метеостанции и год, остальные - температуры воздуха,
начиная с января. Значения разделяются пробелами, при этом количество пробелов варьируется
от 1 до 3. Значения температур, которые не были зафиксированы метеостанцией заменяется
пробелами, т.е. в массиве допускается строка вида: 

20667 2014   5.5   2.4   7.9   8.1              42.7              10.1            


Необходима регулярка, которая бы разбивала эту строку на массив вида:

['20667','2014','5.5','2.4','7.9','8.1','','','42.7','','','10.1','','']

    


Ответы

Ответ 1



По описанию ваших входных данных, похоже что это fixed-width файл. В этом случае будет очень удобно воспользоваться Pandas модулем: import pandas as pd cols = ['id', 'year'] + ['m{}'.format(i) for i in range(1, 13)] df = pd.read_fwf(r'D:\temp\.data\655212.txt', header=None, names=cols) print(df) Результат: In [136]: df Out[136]: id year m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 0 20046 2005 27.0 44.3 9.0 15.9 3.6 9.2 9.2 37.5 18.3 18.6 24.4 26.0 1 20047 2005 26.5 NaN 7.5 17.3 NaN NaN 10.2 39.9 19.7 NaN 20.4 20.0 Также можно воспользоваться идеей от @jfs для того чтобы назвать столбцы по именам месяцев: import calendar cols = ['id', 'year'] + list(calendar.month_abbr)[1:] df = pd.read_fwf(r'D:\temp\.data\655212.txt', header=None, names=cols) Результат: In [139]: df Out[139]: id year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec 0 20046 2005 27.0 44.3 9.0 15.9 3.6 9.2 9.2 37.5 18.3 18.6 24.4 26.0 1 20047 2005 26.5 NaN 7.5 17.3 NaN NaN 10.2 39.9 19.7 NaN 20.4 20.0 Исходный файл: 20046 2005 27.0 44.3 9.0 15.9 3.6 9.2 9.2 37.5 18.3 18.6 24.4 26.0 20047 2005 26.5 7.5 17.3 10.2 39.9 19.7 20.4 20.0

Ответ 2



Предполагая, что под каждую температуру месяца отводится ровно 6 позиций (фиксированная ширина полей), можно распознать данные со стандартного ввода или из файлов, заданных в командной строчке, используя fileinput стандартный модуль: #!/usr/bin/env python import fileinput width = 6 for line in fileinput.input(): station_id, year, s = line.split(None, 2) s = s.rstrip('\n').rjust(12 * width) # pad with leading space temps = [s[i:i+width].strip() for i in range(0, len(s), width)] print(temps) Пример $ python parse-fixed-width-temps.py input.txt ['27.0', '44.3', '9.0', '15.9', '3.6', '9.2', '9.2', '37.5', '18.3', '18.6', '24.4', '26.0'] ['5.5', '2.4', '7.9', '8.1', '', '', '42.7', '', '', '10.1', '', '']

Ответ 3



Если предположить, что каждая строка имеет фиксированную длину (82 символа), и под каждый месяц в строке отведено 5 символов (XX.XX), получаем, что разделителем должны быть два пробельных символа. Значит, можно заменить лишние пробелы на отсутствующее значение + пробелы-разделители, и попробовать поделить строку следующим образом: data = '20667 2014 5.5 2.4 7.9 8.1 42.7 10.1 ' print [val.strip() for val in data.replace(' ', ' n/d ').split(' ')] >>> ['20667 2014', '5.5', '2.4', '7.9', '8.1', 'n/d', 'n/d', '42.7', 'n/d', 'n/d', '10.1', 'n/d', 'n/d']

Перечеркнутый текст по диагонали

#html #css


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

Вопрос: Какие есть оптимальные варианты для верстки перечеркнутого текста по диагонали
для строки разной длины?



.str {
  position: relative;
  display: inline-block;
}

.str:after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: red;
  transform: rotate(-10deg);
}
Lorem ipsum.


Ответы

Ответ 1



Самый просто способ , работает со любой разумной длиной p{ white-space:pre; position:relative; display:inline-block; font-size:20px; } p:after{ content:""; display:block; position:absolute; left:0;top:50%; color:red; width:100%; height:0; border-bottom:2px solid red; transform:rotate(-1deg); }

Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.

Praesent sapien massa,Praesent sapien massa, convallis a pellentesque nec, egestas non nisi.

Praesent sapien massa, convallis



Ответ 2



Могу предложить вот такой хак. Создается тег с классом, который обозначает зачеркивание. И в него скриптом добавляется svg зачеркивание. Тогда работает со строкой любой длины: HTML:
SK tslk ser; k;stlk esl;kt sdasfasfasfasfwshgf srg ser se t
CSS b{position:relative;} svg{width:100%;position:absolute;height:100%;left:0;} JS $(".trow").append(""); Пример: https://jsfiddle.net/v8vb6a8s/

Ответ 3



.strikethrough { position: relative; } .strikethrough:before { position: absolute; content: ""; left: 0; top: 50%; right: 0; border-top: 1px solid; border-color: inherit; -webkit-transform:rotate(-5deg); -moz-transform:rotate(-5deg); -ms-transform:rotate(-5deg); -o-transform:rotate(-5deg); transform:rotate(-5deg); } Deleted text

Как сделать placeholder для select

#javascript #html #jquery #css #html_select


Как сделать так, чтобы при выборе, к примеру, США, слова Выбранная страна оставались.
То есть Выбранная страна: постоянно должны быть внутри независимо от выбора страны.







    


Ответы

Ответ 1



Сделать можно так: помещаем select в отдельный контейнер, например, .block; добавляем в .block еще один блок, например, .placeholder, в который будем выводить текст "Выбранная страна:" + текст выбранной option, и располагаем его поверх select; для .placeholder в css указываем pointer-events:none;, чтобы не припятствовать клику по select На jQuery это будет выглядеть вот так: function selPlaceholder(block) { var placeholder = block.find('.placeholder'), select = block.find('select'); placeholder.text(placeholder.attr('data-text') + select.find('option:selected').text()); } $('.block').each(function() { selPlaceholder($(this)); }); $('.block select').on('change', function() { selPlaceholder($(this).closest('.block')); }); .block, .block select { position: relative; width: 300px; font-family: 'Arial'; font-size: 12px; } .block .placeholder { position: absolute; z-index: 1; left: 5px; top: 2px; pointer-events: none; background: #fff; }






Ромбовидные элементы галереи и двухцветная заливка чисел css

#html #css #вёрстка


Какое наиболее оптимальное решение для реализации плитки галереи в виде ромбов, как
на рисунке ниже, моим решением является два rotate, но тогда приходится задавать отрицательные
margin, что-то вроде, но масштаб нужен desktop:



.work-portfolio__items {
    margin: 0 70px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    
}

.work-portfolio__item {
    width: 260px;
    height: 260px;
    margin: -20px;
    overflow: hidden;
    position: relative;
    display: flex;
    align-items: center;
    transform: rotate(45deg);
    background-color: #212121;
    color: #f5f5f5;
    font-size: 15px;
    line-height: 12.5px;
}

.work-portfolio__item::before {
    content: '+';
    font-size: 20px;
    transform: rotate(45deg);
    display: block;
    position: absolute;
    bottom: -9px;
    left: calc(100% - 42px);
    width: 35px;
    height: 35px;
    z-index: 1;
}

.work-portfolio__item::after {
    content: '';
    display: block;
    position: absolute;
    bottom: 0px;
    left: calc(100% - 35px);
    width: 35px;
    height: 35px;
    background-color: #cd2929;
}







Во втором случае, как лучше сделать, чтобы было 2 цвета у числа при том, что число
находится на разных цветовых background? из вариантов в голову приходит: просто вставить
картинку, использовать каким-то образом градиент


    


Ответы

Ответ 1



Вариант clip-path * { padding: 0; margin: 0; box-sizing: border-box; font-family: 'Segoe UI', sans-serif; } .work-portfolio__items { margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 600px; } .work-portfolio__items ul{ padding: 0; text-align: center; display: flex; flex-wrap: wrap; align-items: center; } .work-portfolio__items ul > li{ list-style: none; width: 50%; } .work-portfolio__items ul > li:nth-child(3n + 3){ width: 100%; margin: -120px 0; } .work-portfolio__item { display: flex; align-items: center; justify-content: center; margin: 0 auto; width: 260px; height: 260px; overflow: hidden; position: relative; background-color: #212121; color: #f5f5f5; font-size: 15px; line-height: 12.5px; -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } .work-portfolio__item::before { content: '+'; font-size: 20px; display: block; position: absolute; bottom: 0; left: 50%; width: 35px; height: 35px; line-height: 30px; text-align: center; margin-left: -17.5px; z-index: 1; background: #CD2929; -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } @media screen and (max-width: 767px) { .work-portfolio__items ul > li:nth-child(3n + 3){ width: 50%; margin: 0; } } @media screen and (max-width: 640px) { .work-portfolio__items ul > li, .work-portfolio__items ul > li:nth-child(3n + 3){ width: 100%; } } Цифры * { padding: 0; margin: 0; box-sizing: border-box; font-family: 'Segoe UI', sans-serif; } .rhombs { display: flex; flex-wrap: wrap; } .rhomb { width: 150px; height: 150px; margin: 25px auto; position: relative; overflow: hidden; background: #CD2929; -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } .rhomb:before { content: ''; position: absolute; top: 1px; left: 1px; bottom: 1px; right: 1px; background: #F5F5F5; -webkit-clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); } .rhomb__inner { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 50%; background: #CD2929; overflow: hidden; } .rhomb__number { position: absolute; top: 50%; left: 50%; font-size: 50px; font-weight: 700; color: #CD2929; transform: translate(-50%, -50%); } .rhomb__number--2 { color: #fff; top: 0; }
62
62
100
100
15
15


Ответ 2



Сделаем ромбы через обычный квадрат с повёрнутым псевдоэлементом. Для адекватных отступов, чтобы эти ромбы не налазили друг на друга применяем формулу a × (√2 - 1) / 2, где a — это высота и ширина квадрата. Вычислим константу (√2 - 1) / 2 ≈ 0,2071067811865475. Демонстрация самого принципа: .rhomb { width: 100px; height: 100px; position: relative; /* смещение чтобы не налезать на другие элементы */ /* это аналогичино margin: calc(100px * (1.414213562373095 - 1) / 2)); */ margin: calc(100px * 0.2071067811865475); /* стили для того чтобы элемент не занимал всю строку */ /* и для центрирования текста вертикально и горизонтально */ display: inline-flex; align-items: center; justify-content: center; } .rhomb:after { content: ""; /* абсолтное позиционирование */ position: absolute; /* занимаем столько же места, сколько контейнер */ left: 0; right: 0; top: 0; bottom: 0; /* окрашиваем в нужный цвет */ background-color: red; /* вращаем на 45 градусов */ transform: rotate(45deg); /* отрицательный z-index, чтобы не перекрывать контент главного блока */ z-index: -1; }
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Следующая проблема в том, что я не знаю как расположить элементы (и, видимо, это невозможно) как на макете адаптивно и не используя JavaScript. Поэтому покажу демонтрация для фиксированной разметки для трёх ромбов в ширину. Эту же разметку можно чуть модифицировать и использовать JavaScript. Надо только на resize убирать и навешивать rhomb--even-row. .rhombs-container { display: flex; justify-content: center; } .rhombs { display: flex; flex-wrap: wrap; /* максимум 3 ромба учитывая также margin 10px */ width: calc(3 * 100px * 1.414213562373095 + 60px); outline: 2px dotted gray; } .rhomb { width: 100px; height: 100px; position: relative; /* смещение чтобы не налезать на другие элементы */ /* это аналогичино margin: calc(100px * (1.414213562373095 - 1) / 2) + 10px); */ margin: calc(100px * 0.2071067811865475 + 10px); /* стили для того чтобы элемент не занимал всю строку */ /* и для центрирования текста вертикально и горизонтально */ display: inline-flex; align-items: center; justify-content: center; } .rhomb:after { content: ""; /* абсолтное позиционирование */ position: absolute; /* занимаем столько же места, сколько контейнер */ left: 0; right: 0; top: 0; bottom: 0; /* окрашиваем в нужный цвет */ background-color: red; /* вращаем на 45 градусов */ transform: rotate(45deg); /* отрицательный z-index, чтобы не перекрывать контент главного блока */ z-index: -1; } /* арифметика смещения элементов чётных строк */ .rhomb--even-row { margin-top: calc(-100px / 2 * 1.414213562373095 + 20px); margin-left: calc(100px / 2 * (1.414213562373095 + 0.2071067811865475 * 2) + 20px); margin-bottom: calc(-100px / 2 * 1.414213562373095 + 20px); } .rhomb--even-row + .rhomb--even-row { margin-left: calc(100px / 2 * 0.2071067811865475 + 20px); }-
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Это же ромб
Для чисел также подойдёт данная техника в сочении с градиентами (не включая случай с MARKETING, 62. Демонстрация: body { background-color: #ccc; } .rhombs-container { display: flex; justify-content: center; } .rhombs { display: flex; flex-wrap: wrap; /* максимум 3 ромба учитывая также margin 10px */ justify-content: space-around; } .rhomb { width: 100px; height: 100px; position: relative; /* смещение чтобы не налезать на другие элементы */ /* это аналогичино margin: calc(100px * (1.414213562373095 - 1) / 2) + 10px); */ margin: calc(100px * 0.2071067811865475 + 10px); /* стили для того чтобы элемент не занимал всю строку */ /* и для центрирования текста вертикально и горизонтально */ display: inline-flex; align-items: center; justify-content: center; /* Стили для чисел */ font-size: 50px; color: #fff; font-weight: bold; } .rhomb:after { content: ""; /* абсолтное позиционирование */ position: absolute; /* занимаем столько же места, сколько контейнер */ left: 0; right: 0; top: 0; bottom: 0; /* окрашиваем в нужный цвет */ border: 1px solid #cd2a2a; /* вращаем на 45 градусов */ transform: rotate(45deg); /* отрицательный z-index, чтобы не перекрывать контент главного блока */ z-index: -1; } .rhomb:nth-child(1):after { background-image: linear-gradient(to left top, #cd2a2a 95%, transparent 0); } .rhomb:nth-child(2):after { background-image: linear-gradient(to left top, #cd2a2a 77%, transparent 0); } .rhomb:nth-child(3):after { background-image: linear-gradient(to left top, #cd2a2a 99%, transparent 0); } .rhomb:nth-child(4):after { background-image: linear-gradient(to left top, #cd2a2a 62%, transparent 0); } .rhomb:nth-child(5):after { background-image: linear-gradient(to left top, #cd2a2a 85%, transparent 0); }
95
77
99
62
85
Для установки градиента (случай MARKETING, 62) на шрифте ромба можно прибегнуть к комбинации свойств -webkit-background-clip: text; и -webkit-text-fill-color: transparent; (ну и разумеется самого градиента). Но и тут нам не обойтись без дополнительных градиентов и математики. Результат: body { background-color: #ccc; } .rhombs-container { display: flex; justify-content: center; } .rhombs { display: flex; flex-wrap: wrap; /* максимум 3 ромба учитывая также margin 10px */ justify-content: space-around; } .rhomb { width: 100px; height: 100px; position: relative; box-sizing: content-box; /* смещение чтобы не налезать на другие элементы */ /* это аналогичино margin: calc(100px * (1.414213562373095 - 1) / 2) + 10px); */ margin: calc(100px * 0.2071067811865475); /* стили для того чтобы элемент не занимал всю строку */ /* и для центрирования текста вертикально и горизонтально */ display: inline-flex; align-items: center; justify-content: center; /* Стили для чисел */ font-size: 80px; color: #fff; font-weight: bold; /* текст принимает картинку фона */ -webkit-background-clip: text; -webkit-text-fill-color: transparent; } .rhomb:after { content: ""; /* абсолтное позиционирование */ position: absolute; /* занимаем столько же места, сколько контейнер */ left: 0; right: 0; top: 0; bottom: 0; /* добавляем границу */ border: 1px solid #cd2a2a; /* вращаем на 45 градусов */ transform: rotate(45deg); /* отрицательный z-index, чтобы не перекрывать контент главного блока */ z-index: -1; } .rhomb:nth-child(1) { background-image: linear-gradient(to top, currentColor calc(95% + (95% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(2) { background-image: linear-gradient(to top, currentColor calc(77% + (77% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(3) { background-image: linear-gradient(to top, currentColor calc(99% + (99% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(4) { background-image: linear-gradient(to top, currentColor calc(62% + (62% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(5) { background-image: linear-gradient(to top, currentColor calc(85% + (85% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(6) { background-image: linear-gradient(to top, currentColor calc(25% + (25% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(7) { background-image: linear-gradient(to top, currentColor calc(35% + (35% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(8) { background-image: linear-gradient(to top, currentColor calc(45% + (45% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(9) { background-image: linear-gradient(to top, currentColor calc(55% + (55% - 50%) * 0.414213562373095), #cd2a2a 0); } .rhomb:nth-child(1):after { background: linear-gradient(to left top, #cd2a2a 95%, transparent 0); } .rhomb:nth-child(2):after { background-image: linear-gradient(to left top, #cd2a2a 77%, transparent 0); } .rhomb:nth-child(3):after { background-image: linear-gradient(to left top, #cd2a2a 99%, transparent 0); } .rhomb:nth-child(4):after { background-image: linear-gradient(to left top, #cd2a2a 62%, transparent 0); } .rhomb:nth-child(5):after { background-image: linear-gradient(to left top, #cd2a2a 85%, transparent 0); } .rhomb:nth-child(6):after { background-image: linear-gradient(to left top, #cd2a2a 25%, transparent 0); } .rhomb:nth-child(7):after { background-image: linear-gradient(to left top, #cd2a2a 35%, transparent 0); } .rhomb:nth-child(8):after { background-image: linear-gradient(to left top, #cd2a2a 45%, transparent 0); } .rhomb:nth-child(9):after { background-image: linear-gradient(to left top, #cd2a2a 55%, transparent 0); }
95
77
99
62
85
25
35
45
55
Небольшая заметка: Я использую 0 как ступенях градиентов, чтобы не дублировать предыдущие значения, так как по спецификации ступенька градиента не может быть меньше предыдущего значения. If a color-stop has a position that is less than the specified position of any color-stop before it in the list, set its position to be equal to the largest specified position of any color-stop before it.

В чём разница между using и on в join-запросах?

#sql


Сабж в заголовке, т.е. равносильны ли запросы (если mysql рассматривать)

SELECT * FROM `tab1` RIGHT JOIN `tab` ON `table2`.`id` = `table1`.`id`  


и

SELECT * FROM `tab1` RIGHT JOIN `tab2` USING(`id`)


если нет, то какой лучше и в чём различие?
    


Ответы

Ответ 1



USING (column_name(s)), по сути, является синтаксическим сахарочком над ON. Согласно докам — служит для указания списка столбцов, которые должны существовать в обеих таблицах. Такое выражение USING, как: A LEFT JOIN B USING (C1, C2, C3, ...) семантически идентично выражению ON: A.C1 = B.C1 AND A.C2 = B.C2 AND A.C3 = B.C3,... В то время как ON можно "склеить" столбцы с различными именами. Но с ON можно проделать операций чуть больше, например можно присоединить не только колонку, но и набор колонок или даже целое условие, пример: SELECT * FROM world.City JOIN world.Country ON (City.CountryCode = Country.Code) WHERE ... Дополнительно USING — при перечислении полей в запросе не обязательно указывать префикс: SELECT film.title, film_id // # film_id указан без префикса FROM film JOIN film_actor USING (film_id) WHERE ... Тоже самое с ON: SELECT film.title, film.film_id // # film.film_id обязателен префикс FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) WHERE ... Если не перечислять поля явно, а использовать select * для соединения столбцов, то в результирующем наборе при ON колонка "всплывёт" дважды, в то время как с USING — только раз: mysql> create table t(i int); insert t select 1; create table t2 select*from t; Query OK, 0 rows affected (0.11 sec) Query OK, 1 row affected (0.00 sec) Records: 1 Duplicates: 0 Warnings: 0 Query OK, 1 row affected (0.19 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> select * from t join t2 on t.i = t2.i; +------+------+ | i | i | +------+------+ | 1 | 1 | +------+------+ 1 row in set (0.00 sec) mysql> select * from t join t2 using(i); +------+ | i | +------+ | 1 | +------+ 1 row in set (0.00 sec) mysql> инфа позаимствована на enSO MySQL ON vs USING?

Плохо ли использовать публичные переменные класса?

#cpp #code_style


Изучаю С++. Важна скорость. Стоит ли писать методы для одного лишь изменения\получения
переменой встроенного типа? Пользовательского типа? Компилятор сообразит? Или пихнуть
в паблик и обращаться напрямую?

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


Ответы

Ответ 1



Это сделано для соблюдения принципа инкапсуляции в ООП, т.е. скрытия деталей реализации класса от потребителя класса. В большинстве случаев, данные класса имеют прямое отношение к конкретным деталям реализации и требуют контроля со стороны разработчика по установке этих данных для соблюдения инвариантов класса. Т.е. значения должны быть установлены таким образом, что бы класс мог корректно работать. Представь ситуацию, в которой твое поле требует установки не просто любого значения, а конкретных валидных значений (т.е. соблюдения каких-то предусловий). В таких ситуациях отдавать установку значений на откуп пользователя твоего класса было бы опрометчиво: class Rectangle { private: int _width; int _height; public: void setWidth(int width) { if (width > 0) _width = width; ... } }; В данном примере, установка ширины прямоугольника и проверка предусловий (ширина не может быть нулевой или отрицательной) и, как следствие, соблюдения инварианта класса (не может быть прямоугольника с отрицательной или нулевой шириной) прямая обязанность класса Rectangle, так как пользователь может ничего не знать о внутреннем устройстве вашего класса и устанавливать любые значения, в том числе некорректные.

Ответ 2



Это сделано не только из соблюдения принципа инкапсуляции. Допустим, у вас класс Прямоугольник с его параметрами x₁, y₁, x₂, y₂. Если объекты сперва создаются, а только потом используются без изменений (такое бывает часто), нет проблем, можете присвоить значения свойствам напрямую. В относительно новом языке TypeScript, если я ничего не путаю, свойства даже могут задаваться в интерфейсах. ООП же подразумевает задачи со сложными связями между объектами. Это значит, например, что ваш прямоугольник уже нарисован где-то в объекте класса Полотно. Что даст простое изменение свойства? Ничего. Прямоугольник должен быть перерисован при изменении свойства.

как занулить первые 4 бита в байте на java

#java #hex


Предположим что есть байт b = 63. В битах это будет 0011 1111.
Как можно занулить первые 4 бита чтобы получилось 0000 1111?
Делаю чтобы можно было приводить байты к 16-ричной системе.
Для зануления последних 4х битов использую сдвиг >>.
    


Ответы

Ответ 1



Чтобы из 0b0110_0010 получить 0b0000_0010, чтобы обнулить первые 4 бита, считая слева-направо (как люди на бумаге пишут): b &= 0b0000_1111; // & 0x0f Чтобы из 0b0110_0010 получить 0b0000_0110, чтобы обнулить первые 4 бита, считая справа-налево: b = (byte) ((b & 0b1111_0000) >> 4); // & 0xf0) >> 4 В данном случае нет разницы между >> и >>>. Для байта легко напечатать все возможные значения, чтобы выбрать желаемое поведение слева или справа очищать биты. Кстати: 63 == 0b0011_1111, а не 0b0110_0010 и даже 0x63 == 0b0110_0011 не равно 0b0110_0010.

Ответ 2



Используя, например, побитовые операторы >>>= Сдвиг вправо с заполнением нулями с присваиванием public static void main(String[] args) { byte b = 63; System.out.println(b); b >>>= 4; System.out.println(b); } Результат: 63 3

Продление жизни значения константной ссылкой

#cpp #шаблоны_с++ #ссылки #language_lawyer #неопределенное_поведение


Как известно, если rvalue передаётся в некую функцию через константную ссылку, то
время его жизни продлевается. Т. е. в следующем примере оно точно живёт пока выполняется
функция ref_to_ptr. Вопрос в том, насколько долго обязано жить такое значение и допустимо
ли его использование в функции print, либо же это UB с разыменованием потенциально
мусорного указателя?

https://ideone.com/CcacHz

#include 

using namespace std;

template  const T *ref_to_ptr(const T &x)
{
  return &x;
}

void print(const int *val)
{
  cout << *val << endl;
}

int main()
{
  print(ref_to_ptr(42));
  return 0;
}

    


Ответы

Ответ 1



Насколько я понимаю стандарт (цитата): ⁴ [...] Temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created. [...] ⁵ There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression. [...] ⁶ The third context is when a reference is bound to a temporary object. The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference [...] The exceptions to this lifetime rule are: (6.9) — A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call. (6.10) — The lifetime of a temporary bound to the returned value in a function return statement is not extended; the temporary is destroyed at the end of the full-expression in the return statement. Иными словами: обычно временный объект, на который ссылается ссылка, умирает вместе со ссылкой. Но если вы передаёте в функцию временный объект как аргумент для ref-параметра, время жизни этого временного объекта продлевается до конца всего выражения, содержащего вызов функции. Это значит, что время жизни параметра x заканчивается в конце строки print(ref_to_ptr(42)); то есть доступа к «умершему» объекту нет. Это также, судя по всему, означает, что переписав код следующим образом: const int *ptr = ref_to_ptr(42); print(ptr); вы получите таки undefined behaviour, т. к. время жизни временного объекта, на который указывает ptr, заканчивается после первой строки!

Ответ 2



Добавлю критерий истины :) - практику. В подтверждение точки зрения @VladD приведу такой код: #include using namespace std; template const T *ref_to_ptr(const T &x) { return &x; } class Test { public: Test() { cout << "ctor: " << this << endl; } ~Test() { cout << "dtor: " << this << endl; } }; void print(const Test * val) { cout << val << endl; } int main() { print(ref_to_ptr(Test())); const Test * ptr = ref_to_ptr(Test()); print(ptr); cout << "The end.\n"; return 0; } Сей код ведет себя одинаково в VC++ и в GCC, демонстрируя, что временный объект умирает уже после вызова print, но сразу же после него.

Как данный код на stream может компилироваться и работать?

#java


Как данный код может выполняться и компилироваться если при action.perform, метод
perform даже не определен. И плюс команда типа editor в момент m.record(editor::save);,
а сам список macro преназначен для объектов типа action? Как такое может быть?

public class Macro {
    List macro;

    Macro(){
        macro = new ArrayList<>();
    }

    public void record(Actiona action){
        macro.add(action);
    }

    public void run(){
        macro.forEach(Actiona::perform);
    }

    public static void main(String[] args) {
        MockEditor editor = new MockEditor();
        Macro m = new Macro();
        m.record(editor::save);
        m.record(editor::close);
        m.run();
    }
}

public class MockEditor implements Editor {

    @Override
    public void save() {
        System.out.println("Save");
    }

    @Override
    public void close() {
        System.out.println("close");
    }
}

public interface Actiona {
    public void perform();
}

public interface Editor {
    public void save();
    public void close();
}

    


Ответы

Ответ 1



Эту магию легко понять, если пойти в IDE (скажем IDEA) и попросить заменить лямду на анонимный класс: public static void main(String[] args) { MockEditor editor = new MockEditor(); Macro m = new Macro(); m.record(new Actiona() { // вместо m.record(editor::save); @Override public void perform() { editor.save(); } }); m.record(new Actiona() { // вместо m.record(editor::close); @Override public void perform() { editor.close(); } }); m.run(); // Вызываем метод с двумя объектами Actiona И неожиданно все становится простым и понятным, мы реализуем метод perform вызывая внутри методы editor.save() и editor.close(), так что поведение вполне корректное. Очень хорошое умение, как только запутался в ламбда-функциях, заменяй их мысленно (или с помощью IDE) на анонимные классы и жить становится проще.

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

#linux #git #firefox


Нужно делать коммит профиля Firefox, каждый раз после его закрытия. Как понять что
FF закрылся? Не буду я его в процессах постоянно мониторить. Потому что пользователь
может включить машину, а браузер не запустить и чем то другим заниматься или же наоборот
запускать Firefox по несколько раз в день.
    


Ответы

Ответ 1



Подход у вас неточный. Вместо того, чтобы детектить запущенный процесс Firefox -- лучше мониторьте, что Firefox держит открытым ваш профиль. Вообще, профилей может быть несколько на компьютере, но запущенным будет только один. Определить, что профиль Firefox in use можно по наличию или отсутствию файла: "parent.lock" (Windows), "lock" and ".parentlock" (Linux) ".parentlock" (Mac OS X) Поскольку до компьютера с FF под linux доберусь только к вечеру, то сразу проверить информацию не могу, постараюсь позже дополнить ответ. И ещё. Пока искал инфу -- наткнулся на обсуждение того, что эта фича сломалась и фикс есть только для Windows. Так что пока просто обозначаю направление, куда копать -- а до полноценного решения ещё далеко. Updated. Эм. Смотрите, какая ситуация. На машине под Centos7 в профиле находится ВСЕГДА файл parent.lock - а файл lock находится только когда профиль in use. Похоже, что поломалось только под win. Мне кажется, вам в первую очередь нужно попробовать на своей системе посмотреть, как это у вас работает. Какой у вас дистрибутив Linux?

Ответ 2



например, можно заменить вызов программы вызовом «обёртки». получаете путь к исполняемому файлу: $ which программа переименовываете его, добавив к имени, например, какой-нибудь суффикс: $ sudo mv /полученный/путь /полученный/путь.realprogram а под исходным именем помещаете скрипт-обёртку такого примерно вида: #!/bin/bash # запуск исходной программы: /полученный/путь.realprogram # ваш код, который будет выполняться после # завершения работы исходной программы не забыв добавить этому файлу биты исполнимости: $ sudo chmod +x /полученный/путь

Плавная анимация волнистой линии

#css #css3 #svg #анимация


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

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

Следующий код:    









	






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

Источник 
    


Ответы

Ответ 1



Для получения гладкого перехода из одного состояния в другое, все параметры начального и конечного path должны быть абсолютно одинаковы. "M291,302c0,0,0-40,40-40s177,40,177,40;" "M291,302c0,0,65.3,15.9,148.7-53c50-41.3,68.3,53,68.3,53" Два пути у вас отличаются наличием параметра "s" в формуле конечного пути. Кроме того количество узловых точек неодинаково. Нужно привести формулы обоих путей к одинаковому количеству точек и одинаковому набору параметров. Для этого в векторном редакторе нужно начальный путь трансформировать в конечный путь с сохранением количества узловых точек. У вас параметр "s" управляет второй узловой точкой начального пути. Достаточно его немного сдвинуть в векторном редакторе, и он исчезнет из формулы пути. Сохраняете в векторном редакторе файл в *.svg, но не закрываете редактор. Копируете в свое приложение анимации формулу начального пути. d="m291 302c0 0 129 1 173-33 32-24 40 41 40 41" Повторно редактируете изображение, перетаскивая узловые точки в расположение конечного пути. Копируете формулу конечного пути в ваше приложение Чтобы анимация перехода из начального положения в конечное и обратно в начальное, выглядела гладко, необходимо указать три позиции пути: "m291 302c0 0 5-40 45-40 40 0 172 40 172 40; m291 302c0 0 129 1 173-33 32-24 40 41 40 41; m291 302c0 0 5-40 45-40 40 0 172 40 172 40" Финальный код анимации: .container { width:100%; height:100%; }
Источник: Smoothly animating wavy line @Alexandr_TT Топики с подобной техникой реализации: Каким образом создаются SVG анимации или трансформации? Tooltip с вырезами у стрелки

Почему временный объект нельзя присвоить неконстантной ссылке?

#cpp #language_lawyer


Почему в стандарте языка сказано, что временный объект нельзя присвоить неконстантной
ссылке?
    


Ответы

Ответ 1



Вступление: вопросы из разряда «почему так сделали в Стандарте» обычно закрывают на enSO, так как ответить могут только члены из комитета по стандартизации, которые принимали это правило, а они, как правило, не присутствуют на SO, чтобы дать ответ. Но данному вопросу повезло, его закрыли по другой причине (дубликат) и после публикации ответов, один из которых я и заимствую. Если бы привязка временного объекта была возможна к неконстантной ссылки, могли бы возникать довольно странные ситуации. Например: void inc(double& x) { x += 0.1; } int i = 0; inc(i); Исходно переменная имеет тип int, но приходит в функцию как ссылка на double. Здесь создаётся временный объект, модификация которого внутри функции, реально ни к чему не приводит. Более того, она нелепа, так как осуществляется попытка увеличить целое на 0.1, что, понятно дело, не является возможным.

Ответ 2



Это касается lvalue-reference. rvalue-reference может быть не const. Вырезка из стандарта C++ (N3691): A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows: ... — Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference. [Example: double& rd2 = 2.0;//error: not an lvalue and reference not const int i = 2; double& rd3 = i;//error: type mismatch and reference not const — end example ]

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

#c_sharp


Помогите разобраться. 

В книге написано:


  Типы, допускающие пустые значения, фактически являются ссылочными
  типами, и переменные этих типов создаются в динамической памяти". Но
  если мы говорим о ссылочных типах, то переменные с адресом на объект
  хранятся же в стеке, а сами объекты в куче.


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

В книге ошибка или я чего-то не понимаю?
    


Ответы

Ответ 1



Это не ошибка, это утверждение, далекое от реальности + кривой перевод. Есть типы значений (value types), есть ссылочные типы (reference types). Переменная value type хранит значение прямо в себе. Для value type после a = b вы получите "в a лежит то же значение, что и в b". Если у вас есть value type Point, то Point b = new Point(5, 5); Point a = b; // скопировали значение b в a a.X = 1; Console(b.X) // 5! Переменная reference type хранит в себе ссылку на объект. Для reference type после a = b вы получите "а ссылается на тот же объект, что и b" Point b = new Point(5, 5); Point a = b; // а теперь указывает (ссылается) на тот же объект Point, что и B a.X = 1; Console(b.X) // 1! Это единственное различие. По поводу хранения. Переменная - это конструкция уровня языка. Переменные не могут "создаваться в динамической памяти". С точки зрения языка нет разницы между стеком и "динамической памятью". Стек - это особенность реализации, и компилятор языка сам решает, где хранить значение переменной. Значения переменных могут хранится в стеке или в динамической памяти. Под значением подразумевается непосредственно значение для value type, и ссылка (адрес) - для reference type. Значения локальных переменных обычно хранятся в стеке. Но при этом утверждения "переменные value types храняться в стеке" или "переменные с адресом на объект хранятся в стеке, а сами объекты в куче" в принципе неверны. Смотрите: Локальная переменная типа value type. Значение (5) скорее всего будет лежать в стеке: int i = 5; Локальная переменная типа reference type. Значение (адрес объекта) скорее всего будет лежать в стеке. Сам объект - в куче. object o = new object(); Пока вроде сходится? Переменная типа value type - поле класса. Объект вместе со всеми полями лежит в куче. Значение переменной value type (5) лежит .. в куче! class A { public int somefield; } //..... A a = new A(); a.somefield = 5; // положили значение 5 внутрь объекта в куче Локальная переменная типа value type, на которую есть замыкание (упоминание переменной внутри анонимного метода). Объявление ничем не отличается от (1), это точно такая же локальная переменная типа int. Но замыкание создает анонимный класс, и переменная на самом деле будет храниться как поле класса. В куче: int i = 5; // чуть ниже в том же методе Action someAction = () => { Console.WriteLine(i); }; Так что если взять цитату из книги (насколько я понял, это "Microsoft Visual C#. Подробное руководство"), и разобрать по частям, то: Все переменные типов значений создаются в стеке. Неверно, см. 3 и 4 выше! Все переменные ссылочных типов (объекты) создаются в динамической памяти (хотя сами ссылки находятся в стеке) Неверно, переменная ссылочного типа != объект. Типы, допускающие пустые значения, фактически являются ссылочными типами, и переменные этих типов создаются в динамической памяти. Неверно, речь о nullable types (например, int?), а они - структуры, value types. Локальные переменные типа int? в случае (1) лежат прямо в стеке - по сути, в стеке лежит структура, в которой одно поле - это флаг "есть ли значение", а второе - само значение.

Как откатить проект до версии на GitHub?

#git #github


Как откатить проект до версии на GitHub? На GitHub лежит проект, я у себя на компе
сделал изменения и даже не коммитил, после понял что лучше этих изменений не делать
и хочу вернуть все как было на момент последнего коммита.
git fetch, git pull пробовал, git clone тоже пробовал, все не то. 
    


Ответы

Ответ 1



Используйте reset: git reset --hard @{u}

Ответ 2



Я в подобных случаях делаю git reset --hard HEAD - это практически то же самое, что и ответ @АлександрГрушко. Существующие файлы, о которых гит не знает, вы не удалите таким способом, но тут уже никак, разве что вы сами удалите эти файлы. (@D-side подсказывает, что можно воспользоваться командой git clean -df – удаляет все файлы в папке, которые не относятся к проекту и не сохранены в репозитории) Альтернативно, можете забрать изменения в карман и тут же его опустошить: git stash git stash drop

Ответ 3



попробуйте git reset --mixed с указанием ветки, должно отмениться ваше добавление без коммита

Ответ 4



Попробуйте использовать git checkout [имя файла], подробнее тут

Ответ 5



Решение: Вижу в вопросе, что вы не делали комит, если также вы не добавляли измененные файлы в индекс командой git add, то можете воспользоваться командой: git checkout -- . Эта команда делает откат изменных файлов к их исходному состоянию, т.е. состоянию когда не было совершенно каких либо изменения. Теория: Откуда Git узнает, на какой ветке вы находитесь в данный момент? Он хранит специальный указатель, который называется HEAD (верхушка). git reset - обновляет индекс, перемещая его на HEAD. git checkout - обновляет рабочую ветку. HEAD будет обновлен в случае, если вы делаете переход с ветки на ветку. О главном: Необходимо понимать что вы хотите получить после ввода команды. Более детально описано здесь - ссылка на статью.

Task vs Thread, сильная задержка Task

#c_sharp #многопоточность


Почему при работе с Task происходят такие задержки?

using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
  static void SomethingLong()
  {
    Thread.Sleep(30000);
  }
  static void Main(string[] args)
  {
    for (int i = 0; i < 20; ++i)
      Task.Run(() => { Console.Write("="); SomethingLong(); });
    for (int i = 0; i < 20; ++i)
      (new Thread(() => { Console.Write("-"); SomethingLong(); })).Start();
    for (int i = 1; i <= 20; ++i)
    {
      Thread.Sleep(1000);
      Console.Write(i.ToString());
    }
  }
}



    


Ответы

Ответ 1



Потому что задачи используют пул потоков. Если при создании задачи в пуле не осталось потоков - то CLR выбирает создавать новый или ставит задачу в очередь. Если заведомо известно что задача будет выполняться долго и другие не должны ее ждать - можно использовать метод Task.Factory.StartNew с опцией TaskCreationOptions.LongRunning.

Артефакты прорисовки теней в рамке с уголком

#html #css


Надо мне сверстать рамку с уголком подобного вида:



Подобных вопросов и на ru so и в сети находится достаточно, чтобы на чистом css и
без картинок. Сделал по гайдлайнам что-то типа:



    .sticky {
        width: 20rem;
    }

    .sticky div {
        position:relative;
        background-color: #FFFFCC;
        padding: 1rem 2rem;
        box-shadow:0 1px 1px rgba(0,0,0,0.2), -1px 1px 1px rgba(0,0,0,0.1);
    }
    
    .sticky div:before {
        content:"";
        position:absolute;
        top:0;
        right:0;
        border-width:0 16px 16px 0;
        border-style:solid;
        border-color:#FFFF99 #fff;
        box-shadow:0 1px 1px rgba(0,0,0,0.1), -1px 1px 1px rgba(0,0,0,0.01);
    }

Some text here

Phone: 322 223

Email: test@example.tld

Я не понял, как сделать диагональную линию, но в принципе, накидав побольше теней получил вполне устраивающий результат в Firefox: Но когда я открываю это всё в Chrome я вижу какую-то уродливую тень, заметную невооружённым глазом (потом пересматривая в FF под лупой вижу, что и там она есть, но не так сильно бросается в глаза) Выключена внешняя тень, оставлена тень от уголка: Выключена тень от уголка, оставлена внешняя тень: Без теней листочек получается какой-то бедный с изобразительной точки зрения, ненастоящий, поэтому у меня возникает следующий вопрос: как кроссбраузерно сделать тень только слева и снизу и чтобы сверху и справа не было не было артефактов?


Ответы

Ответ 1



Box-shadow: blur & spread Используя свойство box-shadow, чаще всего указывают всего три параметра: смещение по X, смещение по Y и размер размытия (blur). При этом незаслуженно забывая ещё об одном параметре — spread. В разных мануалах, его называют по-разному — распространение или сжатие — скорее всего, это потому, что параметр может принимать, как положительные значения, так и отрицательные, в зависимости от задач. А также потому, что например, в Chrome этот параметр нельзя выставить меньше нуля нативным средством в инспекторе стилей (хотя, прописав значение вручную, всё прекрасно отображается и работает, если не двигать ползунок): Так что же делает этот параметр? Интерактивный пример, расставляет всё по местам: .controls{display:flex;justify-content:space-around;text-align:center}.controls input{display:block}:root{--cx:0;--cy:0;--sb:50px;--ss:0}.example{margin:15px auto;width:350px;height:70px;line-height:70px;text-align:center;box-sizing:border-box;border:4px solid #fa0;background-color:rgba(255,255,255,0);box-shadow:var(--cx) var(--cy) var(--sb) var(--ss) rgba(0,0,0,0.5)}
offset_X (-n...n)смещение по X
offset_Y (-n...n)смещение по Y
blur (0...n)размытие
spread (-n...n)распространение
rgba(0, 0, 0, 0.5) 0px 0px 50px 0px
Подведём итоги наблюдений: Смещения — могут быть, как положительными, так и отрицательными; Размытие — это не размер тени, хотя и влияет на её размер визуально. Размытие как бы смазывает границу тени. Может принимать только положительное значение; Распространение — это размер тени, относительно блока, который её отбрасывает. Может принимать, как положительные, так и отрицательные значения. Отрицательное значение не может быть меньше половины меньшего из размеров блока. Например, если height блока 70px, то при значении spread меньше -34px тень просто схлопнется (70 / 2 - 35 = 0). При этом, исчезнет и её размытие, каким бы большим оно ни было, т.к. размывать нечего. После небольшого отступления в теорию, переходим к ответу на вопрос: body { background-color: #d4ebf7; } .sticky, .sticky_right { /* Здесь добавил и изменил стили только для сниппета */ width: 18rem; float: left; margin: 3px; } /********************** * Исправленный стикер * **********************/ .sticky div { position: relative; background-color: #FFFFCC; padding: 1rem 2rem; } .sticky div:before { content: ''; position: absolute; top: 0; right: 0; z-index: 1; border-width: 0 16px 16px 0; border-style: solid; border-color: #FFFF99 #fff; box-shadow: -1px 2px 2px -1px rgba(0, 0, 0, 0.3); } .sticky div:after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: -1; box-shadow: -2px 3px 3px -1px rgba(0, 0, 0, 0.3); } /******************** * Правильный стикер * ********************/ .sticky_right div { position: relative; /* Фон изменён со сплошного на градиент */ background-image: linear-gradient(225deg, transparent 10px, #FFFFCC 10px); padding: 1rem 2rem; } .sticky_right div:before { content: ''; position: absolute; top: 0; right: 0; z-index: 1; border-width: 0 16px 16px 0; border-style: solid; /* Цвет изменён с белого на прозрачный */ border-color: #FFFF99 transparent; box-shadow: -1px 2px 2px -1px rgba(0, 0, 0, 0.3); } .sticky_right div:after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 100%; z-index: -1; box-shadow: -2px 3px 3px -1px rgba(0, 0, 0, 0.3); }

Some text here

Phone: 322 223

Email: test@example.tld

Some text here

Phone: 322 223

Email: test@example.tld

Алгоритм прост, изменения минимальны: :before — в свойстве box-shadow с помощью параметра spread уменьшаем размер тени, но при этом сдвигаем тень ещё больше, в том же направлении, куда она была сдвинута ранее. Добавляем положительный z-index, на всякий случай. :after — добавляем. Выравниваем по левому и нижнему краю. Растягиваем по размерам родителя. Позиционируем с помощью отрицательного z-index за блоком. С box-shadow проводим те же манипуляции, что и с предыдущим блоком — уменьшаем тень четвёртым параметром и сдвигаем влево вниз. Таким образом, за счёт смещений, тень осталась на своём месте, но из-за отрицательного распространения, стала меньше и спряталась под основной блок на противоположных от направления смещений краях. PS Т.к. была замечена, на мой взгляд, ещё одна недоработка — непрозрачность в месте отгиба — добавил рядом ещё вариант для сравнения. Кроссбраузерность напрямую зависит от поддержки linear-gradient.

Практические примеры применения масок svg

#css #html5 #svg #mask


Прочитал эти статьи по теории масок, но не уверен, что понял всё правильно 

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/mask
http://css.yoksel.ru/svg-masks/  

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





Ответы

Ответ 1



Примеры использования маски Немного теории плюс примеры и можно сформулировать простые правила, которые будут помогать в освоении и практическом применении масок. Можно представить маску в виде 2D объекта, например лист любого материала, который расположен между нашими глазами и объектом наблюдения. В листе будут вырезаться отверстия, форма которых задаются элементами svg между тегами Если маска полностью непрозрачна fill="black" мы ничего не увидим.
Маска имеет форму двух окружностей, которые полностью прозрачны,- fill="white" Видим после применения маски, вырезанные части объекта, как они есть на оригинальном изображении.
Цвет заполнения маски находится между чёрным и белым цветом, то есть прозрачность маски будет между 0 и 1 На примере часть маски для левого глаза fill="gray" для правого fill="red"
Обработка фона вне маски Для этой цели в теги добавляется прямоугольник занимающий всё пространство маскируемого объекта Принцип тот же,- для фона вне маски, если fill="white" этот участок останется неизменным. В итоге фон как есть, а зона действия маски зависит от прозрачности, то есть от выбора цвета заливки. Для маски,- это глаза fill="black" становятся непрозрачными.
Теперь фон непрозрачный fill="black" маска fill="white" В этой комбинации маска работает, как clipPath
Фон полупрозрачный fill="red" маска прозрачна fill="white"


Ответ 2



Примеры с подключением прозрачности stroke У базовых элементов SVG: line; polyline, polygon, rect,circle',ellipse,'path есть атрибут - stroke-width задавая ширину и прозрачность которого, можно ещё расширить возможности маски. также представляет интерес использование stroke-dasharray и stroke-dashoffset #1 .container { width:50%; height:50%; }
#2 Несколько окружностей Центр - окружность с самым малым радиусом сделан наиболее прозрачным по сравнению с внешними окружностями
#3
#4 Использование stroke-dasharray Делим окружность на 6 равных сегментов, у которых длина черты - 250px, пробел - 64px
#5 Ещё пример с stroke-dasharray и очень широкой строкой - stroke-width="400"


Узнать тип на этапе компиляции

#cpp


Можно ли определить тип переданных параметров variadic templates, на этапе компиляции?

Хочу использовать static_assert для проверки допустимости передачи параметра в шаблон.

Допустим запретить передачу в шаблон типа float

int main() {

    MyClass  obj; // так можно
    MyClass  obj;          // так тоже
    MyClass  obj;            // а вот так нельзя

    return 0;
} 

    


Ответы

Ответ 1



Как уже ответил @AnT, в C++17 появились fold expressions. Если использование C++17 недоступно, то можно сделать следующим образом: template struct any_of; template struct any_of: any_of {}; template struct any_of: std::true_type {}; template struct any_of: std::false_type {}; //использование template struct MyClass { static_assert(!any_of::value, "float not supported"); }; //... MyClass d1;//ok MyClass d2;//assertion Для понимания работы этого кода предлагаю разобраться сначала с возможной реализацией is_same для двух типов: //Общая версия шаблона наследуется от std::false_type, //что дает сразу готовый член value и операцию преобразования к bool. //false_type::value имеет значение false template struct my_is_same: std::false_type {}; //Весь "фокус" в данной специализации. //Данная специализация будет выбрана, если типы переданные в шаблон одинаковые (T и T). //И эта специализация наследуется от std::true_type, ///и член value равен true template struct my_is_same: std::true_type {}; //... static_assert(my_is_same::value, "failure"); //ок - my_is_same здесь наследник std::true_type static_assert(my_is_same::value, "failure"); //ошибка - my_is_same здесь наследник std::false_type Думаю, прием с наследованием от false_type и true_type понятен. В начальном коде используется еще один прием - наследование в шаблоне класса от самого себя с другим набором аргументов шаблона. Разберем и его на примере первоначального кода. //Общая версия шаблона не реализуется и не используется //Вместо нее будут использоваться специализации template struct any_of; //Данная специализация выбирается если параметров более одного. //any_of в данном случае наследуется от any_of, при этом отсекается параметр HeadType, //т.е. он не передается в качестве аргумента шаблону базового класса. //Таким образом с каждой "ступенью" наследования отсекается один тип из списка аргументов. //при этом отсекается второй тип (HeadType), т.к. первый (CheckType) - //это тот тип, который необходимо проверить. template struct any_of: any_of {}; //Наследование и "отсечение" будет происходить до тех пор, //пока не упремся в одну из следующих специализаций: //Эта специализация будет выбрана, если первый и второй параметры шаблона одинаковы. //Здесь уже используется наследование от std::true_type, //что прерывает цепочку наследования от any_of, //таким образом any_of становится наследником std::true_type, //если хоть один аргументов, переданных изначально в any_of, совпадает с первым аргументом. template struct any_of: std::true_type {}; //если же мы дошли до такого момента, когда остался только проверяемый тип, //значит в списке аргументов any_of не было типов, совпадающих с первым, //поэтому прерываем наследование от any_of наследованием от std::false_type. template struct any_of: std::false_type {}; //Таким образом, если в пакете Args... в any_of есть тип Type, //то any_of станет наследником std::true_type, //в ином случае any_of станет наследником false_type static_assert(any_of::value, "float not supported");//ok - any_of наследник std::true_type static_assert(any_of::value, "float not supported");//ошибка - any_of наследник std::false_type

Ответ 2



Весь template type deduction работает именно на этапе компиляции. То есть, когда вы определяете объект шаблонного класса, компилятор скомпилирует используемый класс именно с подставленным типом в шаблонный параметр. Если вы по каким-то причинам хотите запретить пользователю использовать в качестве параметра какой-то определенный тип, то вы должны запретить конструктор для данного шаблона с таким параметром (типом). Пример : template class Foo { public: T a; }; template class Foo { public: Foo() = delete; }; Если вы попытаетесь создать объект Foo, то компилятор выдаст ошибку. Отвечая на вторую часть вопроса про static_assert. В данном случае можно попробовать определить тип именно так static_assert(std::is_same::value, "retval must be bool"); Принцип использования должен быть понятен

Ответ 3



Для этого фактически и предназначены fold expressions в C++17 #include template class MyClass { static_assert(!(... || std::is_same_v)); };

Как посмотреть когда переменная находится в файле подкачки а когда в оперативной памяти?

#cpp #память #виртуальная_память #системное_программирование


Мой основной вопрос состоит в том что, возможно ли во время работы программы как-то(
с помощью любых средств ) узнавать где находится переменная,хотя бы засечь момент когда
она переносится в файл подкачки.
А также у меня вопрос. Правильно ли я понимаю, что файл подкачки используется только
когда не хватает места в оперативной памяти или если есть долго не использующиеся переменные?
Можно ли задать адрес переменной,а потом по ходу программы смотреть находится ли
эта переменная по заранее заданному адресу в оперативной памяти(на c# с помощью .Net).
И соответственно если ее не будет в оперативной памяти, то она находится в файле подкачки.
Так ли работает адрес у переменной, или он не меняется вне зависимости от того где
находится? 
    


Ответы

Ответ 1



возможно ли во время работы программы как-то узнавать где находится переменная, С уровня софта - нет. С уровня драйвера, или уровня ядра - можно. (через каталог страниц виртуальной памяти). Как конкретно - это очень специфическая область - нужно копать DDK (Driver Development Kit). UPD: Виртуальный адрес переменной (я бы назвал обычный), при смене физического адреса - не меняется. Физический адрес нужен для DMA (используется в драйверах HDD, USB, сетевой и звуковой карт). Если адрес существует в физической памяти - он всегда будет иметь физический адрес (но при запросе физического адреса он вероятне всего будет назначен). хотя бы засечь момент когда она переносится в файл подкачки. С уровня драйвер - может быть. Возможно в ядре есть обработчик, скидывающий страницу на диск - найти и перехватить его займет какое-то время (от месяца до года), и требует хороших знаний в этой области. А также у меня вопрос. Правильно ли я понимаю, что файл подкачки используется только когда не хватает места в оперативной памяти или если есть долго не использующиеся переменные? Алгоритм распределения памяти сложный и сложно-предсказуемый, но есть особенности, я постараюсь все перечислить. Ответ зависит как минимум от двух факторов. Если суммарная памяти всех программ меньше чем обьем оперативки - то да, память может находится в физической памяти. Если нет (сегодня такая ситуация что чаще нет) - то есть большая вероятность, что память может оказаться в файле подкачки. Так же, в случае когда оперативной памяти на всех не хватает и статистика использовании ноль - память уходит в файл подкачки. Если область памяти переменной не используется или она забита просто нолями - то такой кусок памяти может пока его не наполнят - вообще нигде не хранится, и не занимать место ни в физической памяти ни в файле подкачки. Так же вероятность нахождение в файле подкачке зависит от частоты обращений к странице памяти по сравнению с другими программами. Т.е. если вы переменную постоянно пишете/читаете - есть вероятность, что она может оказаться в физической памяти (если других претендетов с более высокой статистикой обращений туда нету). В некоторых ОС (98/ХР и многих других) можно было отключить файл подкачки - тогда - переменная всегда в оперативке. Боюсь что win10 отключение не переживёт:) У OS есть специальная метка в памяти - "невыгружаемая память" (например части ядра). Если эту метку получить - память выгружаться не будет, и всегда будет в оперативке. Как - уровень драйвера. UPD: Важная деталь. Любая память, к которой вот сейчас произошло обращение, и страница под неё отстутствует - то страница выделяется, физическая память добывается (если нет свободной, отбирается у другого процесса, а его скидывается на диск), с файла подкачки считывается, т.е. не видно что её не было. Если это не произошло - тогда это "синий экран смерти", но думаю такого не бывает, там хорошо прописан алгоритм что б этого не случилось. Страница стека, куда указывает esp (rsp) - может быть выгружена, если идет работа с другим процессом, но "по первому требованию" она будет загружена назад. Как итог, хочу сказать 1) Волноваться за память - не стоит. 2) стоит стараться оптимально использовать память (чем меньше используется тем лучше, но не в ущерб алгоритму) 3) желательно знать сколько вашей программе нужно памяти, и взять сколько нужно, чем брать кусками - тогда OS проще предсказать сколько памяти вам нужно - и ПО будет работать быстрее. 4) Нужно знать что есть размер страницы памяти, он равен 8192 либо 4096(раньше было) (можно узнать через АПИ). Желательно большие структуры выравнивать по границам этого к-ва байт - тогда программа будет работать быстрее. Ссылка на мой труд, где я обьяснял поведение с массивом Язык C, глобальные массивы

Ответ 2



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

Ответ 3



В Windows для этого существует функция QueryWorkingSetEx. "Working set" - это набор страниц виртуальной памяти, загруженных в данный момент в физическую память. Если заданный адрес в него не попадает, то в результате QueryWorkingSetEx для него значение флага Valid будет равно нулю, если попадает - единице. Пример на С++: #include #include #include bool IsInPhysicalMemory(PVOID address){ const UINT FLAG_VALID = 0x1; PSAPI_WORKING_SET_EX_INFORMATION info = {0}; info.VirtualAddress = address; BOOL bResult = QueryWorkingSetEx(GetCurrentProcess(),(PVOID)&info,sizeof(info)); if(bResult == FALSE) {printf("QueryWorkingSetEx failed: %d\n",(int)GetLastError());return false;} return ((info.VirtualAttributes.Flags & FLAG_VALID) == FLAG_VALID); } int x = 1; int main(int argc, char* argv[]) { //... bool bResult = IsInPhysicalMemory((PVOID)&x); if(bResult == false) printf("In pagefile\n"); else printf("In physical memory\n"); //... } Пример на C# (требует включения unsafe-кода): using System; using System.Text; using System.Runtime.InteropServices; namespace ConsoleApp1 { unsafe class Program { [DllImport("kernel32.dll")] static extern IntPtr GetCurrentProcess(); [DllImport("Psapi.dll")] static extern int QueryWorkingSetEx( IntPtr hProcess, [In, Out] ref PSAPI_WORKING_SET_EX_INFORMATION pv, uint cb); public struct PSAPI_WORKING_SET_EX_INFORMATION { public IntPtr VirtualAddress; public IntPtr VirtualAttributes; }; public static bool IsInPhysicalMemory(IntPtr address) { PSAPI_WORKING_SET_EX_INFORMATION info = new PSAPI_WORKING_SET_EX_INFORMATION(); info.VirtualAddress = address; int iResult = QueryWorkingSetEx(GetCurrentProcess(), ref info, (uint)Marshal.SizeOf(info)); if (iResult == 0) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); return (((Int64)info.VirtualAttributes & 0x1) == 0x1); } static int y = 1; static void Main(string[] args) { //... fixed (int* p = &y) { if (IsInPhysicalMemory((IntPtr)p)) Console.WriteLine("In physical memory"); else Console.WriteLine("In pagefile"); } //... } } } Можно ли задать адрес переменной,а потом по ходу программы смотреть находится ли эта переменная по заранее заданному адресу в оперативной памяти(на c# с помощью .Net). И соответственно если ее не будет в оперативной памяти, то она находится в файле подкачки. Так ли работает адрес у переменной, или он не меняется вне зависимости от того где находится? Обычно да, адрес переменной в виртуальной памяти фиксирован и не меняется в ходе работы программы. (В C# переменные, которые хранятся в управляемой куче, имеют переменный адрес, но это связано с деятельностью сборщика мусора, а не с перемещением в файл подкачки.) Адрес страницы в физической памяти, соответствующей данному адресу в виртуальной памяти, конечно меняется в ходе того как ОС перемещает страницы. Соответствие физического и виртуального адреса можно получить в windbg в режиме отладки ядра (см. vtop), но программно в usermode, насколько я знаю, нельзя.

Ответ 4



Мой основной вопрос состоит в том что, возможно ли во время работы программы как-то( с помощью любых средств ) узнавать где находится переменная,хотя бы засечь момент когда она переносится в файл подкачки. Вопрос интересный. Надо смотреть WinAPI есть ли там какие-нибудь функции на эту тему. Думаю что таких функций нет, поэтому скорее всего для винды невозможно узнать, выгружена ли данная переменная на диск или болтается в памяти. Кстати, чтобы это узнать, надо еще анализировать карту загрузки и листинг. То есть WinAPI функция (буде такая бы и была) должна была бы в качестве параметров принимать не только имя переменной но и карту загрузки и листинг программы. Думаю, что для линукса такой функции тоже нет. По тем же причинам - никто не будет парсить листинг и карту загрузки в поисках имени, да и формат листинга и карты загрузки не стандартизован. Конечно, в мире линукса есть много затейников. Может быть кто-то и написал нашлепку к ядру, которая отслеживает что-то подобное хотя бы в целях отладки. А также у меня вопрос. Правильно ли я понимаю, что файл подкачки используется только когда не хватает места в оперативной памяти или если есть долго не использующиеся переменные? Теоретически файл подкачки используется, когда не хватает места в оперативной памяти. Практически алгоритм файла подкачки на винде закрыт, поэтому ничего об нем сказать нельзя. Для Линукса алгоритм, конечно, известен матерым линуксоидам. Кстати, коллега nick_n_a подкинул свежую идею. Если отключить файл подкачки, то все переменные будут сидеть в памяти. :-) UPD1: Кстати, да. Есть же еще переменные на стеке. Интересно, а страница стека выгружается в файл подкачки? В любом случае непонятно, если пользователь запросил имя стековой переменной, а эта переменная в данный момент не существует, что должна возвращать WinAPI функция? А может эта стековая переменная и вообще никогда не будет создана в текущем запуске программы? Вобщем, вопрос довольно странный. UPD2: А еще есть такой вариант, что переменная (например структура) имеет размер бОльший, чем страница памяти. Тогда возможен случай, что часть переменной выгружена на диск, а часть нет. Как в этом случае нужно рассматривать переменную - как выгруженную или как не выгруженную? Или если переменная не большая, но лежит на границе страниц. UPD3: А еще есть такой вариант, что переменная расположена в куче и опять же непонятно, была она создана или нет в данный момент работы программы и будет ли вообще когда-нибудь создана в этом запуске программы. Вобщем, видимо Вам преподаватель дал такое задание просто чтобы вы подумали над проблемой. Потому, похоже, что технически эта проблема "в общем виде" не решается. UPD4: Я понял что нужно получить память занимаемую процессом программы в которой находится переменная. Но дело в том что я не понимаю как на c++ это можно реализовать. Sergesama Channel, Вы не стирайте старый вопрос. Просто дописывайте уточнения. Потому что "норот" отвечал на Ваш старый вопрос, Вы его изменили и все ответы выглядят немного шизофренично. :-) Что касается получения памяти процесса, то мне вспоминается, что на винде это можно получить (выгрузить на диск в двоичном виде). Не знаю уж как это соотносится с безопасностью, но вроде бы такая функция в WinAPI была (но точно не скажу, надо смотреть). Но даже если Вы получили образ памяти процесса, то все равно непонятно, какие страницы в данный момент выгружены на диск, а какие нет.

Ответ 5



Технически в современном мире, память делится на виртуальную и физическую. Грубо говоря, физическая память - это набор ячеек и адресов к ним в оперативной памяти. Виртуальная память - отображение адресов физической памяти на некоторые виртуальные адреса с точки зрения процессора. Что это нам дает? Во-первых, отображая физические адреса на виртуальные, мы может изолировать память каждого процесса. Во-вторых, любой процесс может находиться по одинаковому адресу в виртуальной памяти, но всегда в разных местах в физической памяти. В-третьих, мы можем один адрес физической память отображать сразу на несколько адресов виртуальной памяти на каждый процесс, что нам даст возможность разделяемой памяти без лишних дублирований памяти между этими процессами. В-четвертых, благодаря виртуальной памяти, её можно выгружать и загружать обратно при необходимости. Дополнительно виртуальную память можно защищать (например запретить записывать что-то в память с кодом), что было бы невозможно при работе с физической памятью напрямую. При доступе к отсутствующему / выгруженному адресу виртуальной памяти процессор генерирует прерывание / исключение, которое операционная система перехватывает и загружает на нужный виртуальный адрес ранее выгруженную физическую память и после этого настраивает оборажение физического адреса на виртуальный. Теперь, что касается вашего вопроса, с точки зрения программы все её переменные хранятся всегда по одним и тем же виртуальным адресам и всегда доступны (если они недоступны, произойдет исключение и ОС загрузит память будто она всегда была загружена, и сделает это незаметно для программы), но адрес в физической памяти может быть разным и меняться в процессе загрузки / выгрузки как угодно. Если вам это действительно нужно, то копать следует в сторону определения физических адресов на которые отображены виртуальные. Отображение физических адресов на виртуальные происходит настройкой некоторой структуры данных и загрузкой этой структуры в некоторый регистр процессора, после чего процессор делает преобразования между адресами самостоятельно по этой самой структуре. Более подробно можно почитать об этом, найдя информацию по ключевым словам "paging and virtual memory".

Ответ 6



По крайней мере в Линуксе, если верить man 5 proc это возможно. Cудя по описанию, для известного адреса переменной вам нужно прочесть соответствующие 8 байт (uint64_t) (для страниц размером 4k просто сдвиньте адрес на 9, обнулите 3 младших бита и сделайте seek) из файла /proc/self/pagemap и посмотреть на бит 62. Если 0, то страница с переменной в swap-е. /proc/[pid]/pagemap (since Linux 2.6.25) This file shows the mapping of each of the process's virtual pages into physical page frames or swap area. It contains one 64-bit value for each virtual page, with the bits set as fol‐ lows: 63 If set, the page is present in RAM. 62 If set, the page is in swap space 61 (since Linux 3.5) The page is a file-mapped page or a shared anony‐ mous page. 60–57 (since Linux 3.11) Zero 56 (since Linux 4.2) The page is exclusively mapped. 55 (since Linux 3.11) PTE is soft-dirty (see the kernel source file Doc‐ umentation/vm/soft-dirty.txt). 54–0 If the page is present in RAM (bit 63), then these bits provide the page frame number, which can be used to index /proc/kpageflags and /proc/kpage‐ count. If the page is present in swap (bit 62), then bits 4–0 give the swap type, and bits 54–5 encode the swap offset. Before Linux 3.11, bits 60–55 were used to encode the base-2 log of the page size. To employ /proc/[pid]/pagemap efficiently, use /proc/[pid]/maps to determine which areas of memory are actu‐ ally mapped and seek to skip over unmapped regions. The /proc/[pid]/pagemap file is present only if the CON‐ FIG_PROC_PAGE_MONITOR kernel configuration option is enabled. Permission to access this file is governed by a ptrace access mode PTRACE_MODE_READ_FSCREDS check; see ptrace(2).

Перечисления в Си

#c #enum


В чём основные отличия и плюсы использования перечисления в Си (enum) от обычной
инициализации переменных?
    


Ответы

Ответ 1



Основное отличие заключается в первую очередь в том, что элементы enum в языке С являются именованными константами и формируют константные выражения. Альтернативным способом введения именованных констант в языке С являются макросы #define. Других способов нет, и никакая "инициализация переменных" вам здесь не поможет. Вариант с #define, вследствие своей "макросовой" природы, является более гибким, ибо позволяет объявлять константы разных типов. enum позволяет объявлять константы только типа int (или некоего большего знакового целочисленного типа). С другой стороны, объявления enum, в отличие от макросов, подчиняются общим правилам области видимости языка, что может являться несомненным преимуществом. Для локальных целей можно объявить локальный enum. При использовании макросов "локальность" имен приходится эмулировать вручную путем явного применения #undef, что весьма неудобно.

Ответ 2



Перечисления позволяют из всего множества целых чисел выделить именованное подмножество целочисленных констант. То есть перечисления вводят в программу некую новую абстрактную сущность. Это средство классификации констант Сходу в голову приходит следующее.:) Во-первых, перечисления могут использоваться как константы при задании размерностей массивов. Например, enum { N = 10 }; int a[N] = { 0 }; Нельзя написать const int N = 10; int a[N] = { 0 }; Компилятор выдаст сообщение об ошибке, говорящее о том, что нельзя инициализировать массивы переменной длины. Во-вторых, перечисления можно использовать как выражения в метках case. Например, #include int main(void) { enum { Red, Green, Blue } e = Green; switch ( e ) { case Red: puts( "Red" ); break; case Green: puts( "Green" ); break; case Blue: puts( "Blue" ); break; } return 0; } В-третьих, использование типа перечисления в качестве типа параметра функции, является помимо лучшей читабельности еще и самодокументируемым. То есть становится ясно, с какими целочисленными значениями функция имеет дело.К тому же имена типов перечислений не конфликтуют с другими именами. Например, void draw( enum Color color );

Ответ 3



enum это удобные константы объединённые общей структурой. Вы можете конечно написать const int SUNDAY = 1; const int MONDAY = 2; Но enum'ы приятнее читать, код самодокументируется enum Weekday{Sunday, Monday};