Страницы

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

понедельник, 26 ноября 2018 г.

Как получить анимацию svg объекта, который связан через js с другим svg объектом, задавая анимацию только второму?

Имеется две линии. Правый конец черной line1 можно передвигать мышкой. При этом координаты конца зеленой линии line2 зависят от line1 через функцию moveline2.
Далее добавил анимацию первой линии по клику на красный круг. При этом line1 анимируется, а функция moveline2, которая также пускается по этому событию срабатывает один раз и все. Вторая линия остается без анимации, хотя функционально связана с анимированной первой.
Понятно, что по мере того, как идет анимация должны генерироваться какие-то события по которым можно пускать перерисовку второй линии, но как это сделать?
Как заставить двигаться все объекты функционально связанные с единственным, на котором висит анимация? Использую библиотеку svg.js но, видимо, это не принципиально. Документация по библиотеке https://svgdotjs.github.io
var paper = SVG('draw').size('100%', '100%'); var line1 = paper.line(0, 100, 300, 100).stroke({ width: 5 }).style({ cursor: 'pointer' }); var line2 = paper.line(0, 200, 100, 200).stroke({ width: 5 }).attr({ stroke: 'green' }); var circle = paper.circle(30).move(50, 50).fill('red').style({ cursor: 'pointer' }); //перемещение конца line1 примерно под курсор) function move(event) { line1.attr({ x2: event.pageX, y2: event.pageY }) moveline2() //ловим событие перемещения мышки на холсте paper.mousemove(function(event) { line1.attr({ x2: event.pageX, y2: event.pageY }) moveline2() }) paper.mouseup(function() { paper.mousemove(null) }) } //функциональная зависимость координат второй линии от первой (любая) function moveline2() { var x = line1.attr('x2'); var y = line1.attr('y2'); line2.attr({ x2: x / 2, y2: (x + y) / 2 }) } //устанвка функциина нажатие ЛКМ над line1 line1.on('mousedown', move) //анимация по клику circle.click(function() { line1.animate().attr({ x2: 300, y2: 400 }) moveline2() }) #draw { width: 400px; height: 400px; border: 2px solid silver } Пример



Ответ

Для выполнения собственной функции в течение анимации нужно использовать функции during/duringAll
var paper = SVG('draw').size('100%', '100%'); var line1 = paper.line(0, 100, 300, 100).stroke({ width: 5 }).style({ cursor: 'pointer' }); var line2 = paper.line(0, 200, 100, 200).stroke({ width: 5 }).attr({ stroke: 'green' }); var circle = paper.circle(30).move(50, 50).fill('red').style({ cursor: 'pointer' }); //перемещение конца line1 примерно под курсор) function move(event) { line1.attr({ x2: event.pageX, y2: event.pageY }) moveline2() //ловим событие перемещения мышки на холсте paper.mousemove(function(event) { line1.attr({ x2: event.pageX, y2: event.pageY }) moveline2() }) paper.mouseup(function() { paper.mousemove(null) }) } //функциональная зависимость координат второй линии от первой (любая) function moveline2() { var x = line1.attr('x2'); var y = line1.attr('y2'); line2.attr({ x2: x / 2, y2: (x + y) / 2 }) } //устанвка функциина нажатие ЛКМ над line1 line1.on('mousedown', move) //анимация по клику circle.click(function() { line1.animate().attr({ x2: 300, y2: 400 }).during(function(pos, morph, eased, situation) { moveline2() }); }); #draw { width: 400px; height: 400px; border: 2px solid silver } Пример


Vw и Vh или @media

Здравствуйте!
У меня с другом возник спор: что лучше vw и vh или @media-запросы?
Я утверждаю, что vw и vh можно и нужно внедрять в разработку сайтом потому, что эти величины помогают подстраивать сайту под любые разрешения экранов. По-этому я решил создать мини-сайт где эти величины будут везде
div { width: 25vw; height: 25vh; font-size: 5vw; background-color: black; color: white }

DiV

Они маштабируют блоки под все разрешение экранов, при этом сохраняя нормально расположение блоков (как на больших экранах, так и на маленьких). А @media не удобен тем, что там вручную нужно указывать все размеры, которые должны быть не устройствах. Ведь всё равно, никогда не знаешь с какого устройства зайдёт пользователь.
Мой же друг утверждает, что @media лучше, т.к. техника довольно стойкая, используется на многих сайтах и устройствах и он отлично справляется со своей обязанностью подстраиванием. А vw и vh бесполезная вещь, которая в принципе и не нужна во все. Зачем они, если подстраивать можно с помощью @media?
Так что же лучше использовать vw и vh или @media в подстройке сайта под разные экраны?


Ответ

Это совершенно разные вещи, использование которых друг другу никак не противоречит. Задание размеров чего бы то ни было в единицах vw/vh и @media-запросы имеют совершенно разные предназначения.
Используйте vw/vh, когда вам нужно единицы измерения относительно ширины/высоты экрана.
Используйте @media, когда вам нужно разные стили под разные разрешения, под разные устройства, стили чисто для печати и т.д.

Расширение класса перегруженными операторами C#

Имеется класс BigInteger библиотеки BouncyCastle, который имеет функции вида BigInteger.Add(BigInteger), Sub, Multiply и т.д. Так вот, для удобной работы хочется создать перегруженные методы operator+, operator- и т.д, т.е. расширить данный класс. Как это можно сделать правильно и по канонам ООП?
Для пользователя все должно выглядеть примерно так:
BigInteger A=5,B=10; BigInteger C = A+B;


Ответ

Боюсь у вас ничего не получится. Дело в том, что интересующий вас синтаксис - обеспечивается перегрузкой операторов, и без возможности модифицировать исходники класса BigInteger вы эту задачу выполнить не сможете. Теоретически вам могла бы помочь такая возможность, как методы расширения (extension methods), но этот синтаксический сахар применим только по отношению к экземплярам, а перегрузка операторов реализуется статическими методами. Наследование тут вам тоже вряд ли поможет, во всяком случае для получения результата в том виде, в котором вы хотите. Вы, конечно, можете создать класс-наследник BigInteger, перегрузить в нём арифметические операторы с помощью соответствующих статических методов, но эти операторы будут работать только применимо к вашему классу-наследнику, то есть писать что-то вроде
BigInteger A=5,B=10; BigInteger C = A+B;
вы не сможете

Как растянуть пункты меню по всей ширине родительского блока?

Есть обычная навигация
HTML:


CSS:
nav { font-size: 0; line-height: 0; letter-spacing: -1px; }
nav li { display: inline-block; }
nav a { display: block; background: #000; padding: 0 10px; font-size: 17px; line-height: normal; letter-spacing: normal; color: #fff; }
nav li:nth-child(2n) a { background: #666; }
Как пункты меню растянуть по всей ширине блока nav, чтобы padding у всех ссылок был одинаковым (пустого пространства между ссылками быть не должно, это пространство распределяется на внутренние отступы ссылок)?
UPD:
Изображение того, как должно отображаться меню.


Ответ

Поставить display: flex родителю, flex-basis: auto + flex-grow: 1 — потомкам.
body, ul { margin: 0; padding: 0; } ul { display: flex; } ul li { list-style-type: none; flex-basis: auto; flex-grow: 1; background: #000; text-align: center; } ul li:nth-child(2n) { background: #ccc; } ul li a { padding: 20px 0; text-decoration: none; color: #ccc; display: block; } ul li:nth-child(2n) a { color: #000; }


Ускорить загрузку сайта

Здравствуйте. Как лучше организовать хранение фотографий?
Как лучше сохранять изображения от пользователей (аватар, обложка страницы, посты на стене и т.д.). В скольких размерах? Например, миниатюра 60х60, основное фото профиля 200х200, увеличенная версия - 1000х1000. Так? И как тогда это оптимизировать? В скрипте если будет три фото сразу сохраняться, не слишком ли долго будет это происходить?


Ответ

Если это каталог, то можно организовать lazy load. Плагин на jquery
Второй вариант http-кэширование. Детальнее по нему (так же рекомендую почитать).
Ну и делать тумбы. А разрешения вы сами подбираете под свой проект.

Как залить реляционные данные в seeds.rb?

Есть две таблицы - Rubric и Question. Связь многие ко многим. Стоит задача загрузить данные в базу через seeds.rb. Данные хранятся в xls. В принципе, понятно, как загрузить рубрики - берем все данные из ячеек рубрики, сплитим их по запятой, объединяем и заливаем в базу. Непонятно, как сделать привязку Вопросов к этим созданным рубрикам. Или как-то запрос сделать к базе? Подскажите правильный вариант.
| № вопроса | Заголовок | Вопрос | Рубрика | |:-----------|------------:|:------------:|:------------:| | 1 | Заголовок1 | Вопрос1 | наука, политика | 2 | Заголовок2 | Вопрос2 | журналистика | 3 | Заголовок3 | Вопрос3 | погода | 4 | Заголовок4 | Вопрос4 | наука | 5 | Заголовок5 | Вопрос5 | зима, лето, осень


Ответ

В таблице у вас хранятся названия рубрик через запятую. Массив названий рубрик для каждого вопроса. В модели Question вы можете объявить для этих названий виртуальный атрибут (нужен только сеттер). И в нем по принятому массиву - связывать запись Question с записями Rubric, находя или создавая их по названиям.
Вот пример сеттера в модели Question
class Question < ApplicationRecord has_many :rubrics, through: :rubrics_questions has_many :rubrics_questions
def rubric_names=(value) return if value.blank? self.rubrics = value.split(', ').map { |name| Rubric.where(name: name).first_or_initialize } end end
А в seeds.rb вопросы создаются примерно так:
Question.where(id: id).first_or_create(title: title, text: text, rubric_names: rubric_names)

slick slider проблема с активным слайдом

Когда ставится параметр centerMode: true и слайдер бесконечно прокручивается то у клонированного слайда активность не сразу срабатывает, когда карусель листается то центральный блок принимает стили активности, но если начать листать до последнего то у того блока что клонирован, активность не сразу применяется?
$(".slider").slick({ autoplay: true, dots: true, slidesToShow: 3, centerMode: true }); .slider { width: auto; margin: 30px 50px 50px; } .slick-slide { background: #3a8999; color: white; padding: 40px 0; font-size: 30px; font-family: "Arial", "Helvetica"; text-align: center; transition: background 0.8s; } .slick-arrow{ background: #000!important; } .slick-prev:before, .slick-next:before { color: black; } .slick-dots { bottom: -30px; } .slick-current { background: black; }

slide1
slide2
slide3
slide4
slide5
slide6


Ответ

Вот исправленный ответ
$(".slider").slick({ autoplay: true, dots: true, slidesToShow: 3, centerMode: true }); .slider { width: auto; margin: 30px 50px 50px; } .slick-slide { background: #3a8999; color: white; padding: 40px 0; font-size: 30px; font-family: "Arial", "Helvetica"; text-align: center; transition: background 0.8s; } .slick-arrow{ background: #000!important; } .slick-prev:before, .slick-next:before { color: black; } .slick-dots { bottom: -30px; } .slick-center { background: black; }

slide1
slide2
slide3
slide4
slide5
slide6

Изменение атомарного значения из нескольких потоков в Java

Здравствуйте. Помогите, пожалуйста, разобраться со следующей задачей:
Воспользуйтесь классом LongAccumulator для вычисления максимального и минимального накапливаемых элементов.
Подразумевается, что должно быть несколько потоков, а вид генерации элементов произвольный. Вот мой код:
import java.util.Random; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.LongAccumulator;
public class Main { public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE); public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE);
public static void main(String[] args){ Random random = new Random(); // Executor executor = Executors.newCachedThreadPool(); Executor executor = Executors.newFixedThreadPool(1); for (int i = 1; i <= 1000; i++) { int taskId = i; Runnable task = () -> { for (int k = 1; k <= 100_000; k++){ int value = random.nextInt(1_000_000); maxValue.accumulate(value); minValue.accumulate(value); } System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get()); }; executor.execute(task); } } }
Всё работает, но не так, как я ожидал. Если все задачи поместить в один поток (см. строку Executor executor = Executors.newFixedThreadPool(1);), то всё отрабатывает более-менее быстро. Если же вместо этой строки подставить Executor executor = Executors.newCachedThreadPool();, или поставить несколько потоков: Executor executor = Executors.newFixedThreadPool(5);, то код работает в несколько раз дольше. Собственно, вопрос состоит в том, почему это происходит и как сделать так, чтобы разделение задач на потоки не увеличивало время работы программы, а уменьшало.
UPD. По совету, приведённому в комментариях, изменил код следующим образом, и программа стала работать быстрей в многопоточном режиме:
import java.util.Random; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.atomic.LongAccumulator;
public class Main { public static LongAccumulator maxValue = new LongAccumulator(Math::max, Integer.MIN_VALUE); public static LongAccumulator minValue = new LongAccumulator(Math::min, Integer.MAX_VALUE);
public static void main(String[] args){ Executor executor = Executors.newCachedThreadPool(); Runnable task; // вынес объявление из цикла ниже for (int i = 1; i <= 1000; i++) { Random random = new Random(); // для каждой задачи создаётся свой Random int taskId = i; task = () -> { for (int k = 1; k <= 100_000; k++){ int value = random.nextInt(1_000_000); maxValue.accumulate(value); minValue.accumulate(value); } System.out.println(taskId + ": min " + minValue.get() + ": max " + maxValue.get()); }; executor.execute(task); } } }


Ответ

Вынесите объявление Runnable класса из цикла. 1000 потоков (для cachedPool будет именнно так) не даст эффективности - jvm будет между ними переключаться постоянно, а т.к. тело задачи довольно "быстрое" то и эффекта это особо не даст. Поставьте кол-во потоков равным количеству ядер вашего CPU. Random для каждой задачи используйте свой

Viber API отправка сообщений

Здравствуйте. Появилась идея сделать отправку сообщений в public account на Viber через сайт. На оф. сайте ничего толком не понятно как это реализовать. Сам аккаунт уже завел. Например, простая форма: поле и кнопка. хочу при нажатии сделать отправку туда. Как это сделать? (Гугл не помог)



Ответ

Здравствуйте. Вот пример моего кода:
class Viber { private $url_api = "https://chatapi.viber.com/pa/";
private $token = "";
public function message_post ( $from, // ID администратора Public Account. array $sender, // Данные отправителя. $text // Текст. ) { $data['from'] = $from; $data['sender'] = $sender; $data['type'] = 'text'; $data['text'] = $text; return $this->call_api('post', $data); }
private function call_api($method, $data) { $url = $this->url_api.$method;
$options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded
X-Viber-Auth-Token: ".$this->token."
", 'method' => 'POST', 'content' => json_encode($data) ) ); $context = stream_context_create($options); $response = file_get_contents($url, false, $context); return json_decode($response); } } $Viber = new Viber(); $Viber->message_post( '01234567890A=', [ 'name' => 'Admin', // Имя отправителя. Максимум символов 28. 'avatar' => 'http://avatar.example.com' // Ссылка на аватарку. Максимальный размер 100кб. ], 'Test' );
Этот класс можно продолжить добавляя функции к каждому методу.

Как зациклить анимацию (setInterval)

Пишу себе велосипед, кубик должен бесконечно двигаться вправо и возвращаться. Происходит только 1 итерация.Если добавить в left_go() в else if{ setInterval(right_go, 5);} , все работает, но со временем анимация начинает тормозить и зависать. Помогите пожалуйста?
var animate_right = setInterval(right_go, 5);
function right_go () { var left_padding = cube_style.left; if (left_padding!=width_square){ cube.style.left = x +"px"; x++; console.log(left_padding); } else if(left_padding=width_square){ clearInterval(animate_right); var animate_left = setInterval(left_go, 5); } }
function left_go (animate_left) { var left_padding = cube_style.left; if (left_padding!='-1px'){ cube.style.left = x +"px"; x--; console.log(left_padding); } else if(left_padding!=width_square){ clearInterval(animate_left); } }


Ответ

Oбе переменные, animate_left и animate_right, должны быть глобальными, а у Вас clearInterval(animate_left); ничего не делает, так как переменная animate_left в этом месте не определена. Соответственно, таймеры с left_go через каждые 5 миллисекунд накапливаются, и все тормозит.
Код должен быть симметричен относительно left и right
var animate_right = setInterval(right_go, 5); var animate_left = null;
function right_go () { var left_padding = cube_style.left; if (left_padding!=width_square){ cube.style.left = x +"px"; x++; console.log(left_padding); } else if(left_padding=width_square){ clearInterval(animate_right); animate_left = setInterval(left_go, 5); // !!! no var } }

Как вернуть мета информацию из HEAD запроса используя Retrofit2?

Для взаимодействия с сервером использую ретрофит. Есть GET запрос который возвращает огромное кол-во данных. Чтобы каждый раз не съедать трафик клиента нужно проверять обновились ли данные га сервере. Для этого использую HEAD запрос к тому же эндпоинту. Проблема в том что HEAD запрос в Call<> можно положить только Void иначе выкидывает эксепшен. А при таком запросе в колбэк ничего не возвращается, так как у этого запроса нет респонса. Немного погуглив я нашел способ все же получить нужную мне метаинформацю из хедеров в Interceptor.
chain.proceed(request).header("etag"))
Но тут меня настигла очередная проблема, как без колбэка передать этот "етаг" туда откуда был сделан реквест? Должен же быть какой нибудь адекватный/элегантный способ?


Ответ

Retrofit2 корректно возвращает респонс в коллбек при HEAD запросах. Данный код у меня отлично работает:
Call c = service.headRequest(url);
c.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { response.headers(); }
@Override public void onFailure(Call call, Throwable t) {
} });
response не пустой и содержит в себе хедэры response.headers(). Если в вашем случае это не работает, то возможно, что проблема в сервере, который некорректно обрабатывает HEAD запросы.

Поиск элемента в HTML документе с помощью PHP

Как в PHP можно найти нужный элемент в HTML документе или строке, аля get_file_content($htmlString);
Например, есть сайт site.ru у него в "голове" есть скрипт Нужно проверить, существует ли этот тег с атрибутом src на сайте


Ответ

Можете воспользоваться PHP Simple HTML DOM Parser
// Забираете всё что находится по ссылке $html = file_get_html('http://site.com/');
//Ищите ваш тег, если не найдет вернет null (если я не ошибаюсь) $el = $html->find('script[src=site.ru]', 0);
Больше примеров доступно по ссылке выше.

Перевод числа в массив байтов

Как представить число (int, float) в виде массива байтов в Java?


Ответ

Для этого можно воспользоваться ByteBuffer-ом:
int value = 100000; byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
и
float floatValue = 100.5f; byte[] floatBytes = ByteBuffer.allocate(4).putFloat(floatValue).array();

Обращение к *.so по относительному пути

Есть библиотека libsvsynth.so, идущая в комплекте с программой, которая её использует. Т.к. библиотека не устанавливается в систему (программа задумывалась, как физически переносимая), то к путь к ней в функции dlopen описывается как ./libsvsynth.so
При использовании:
$ ./prog
Всё работает - библиотека подключается. Однако, если написать
$ ./parent_dir/prog
То библиотека программой обнаружена не будет (как я понял, библиотека будет искаться в вызываемом каталоге)
Что же нужно сделать для того, чтобы программу можно было запускать без проблем из любого места, а не только из каталога с бинарником+библиотекой?


Ответ

Итак, проблема была решена следующим образом: к программе всё же пришлось добавить shell-скрипт (start.sh) следующего содержания:
#!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" cd $DIR ./prog $@
Затем делаем chmod +x ./start.sh и запускаем из любого каталога в системе

Как сделать такие линии между блоками?

Имеется такая вёрстка блоков:
* { width:576px; } .item { border: 1px #dededc solid; height: 232px; } #four-blocks { overflow: hidden; } #four-blocks .item { width: 280px; float: left; margin-bottom: 10px; } #four-blocks .item:nth-child(1), .item:nth-child(3){ margin-right: 11px; /*box-shadow: 0 3px 0 3px coral;*/ }


Нужно, чтобы по горизонтали и по вертикали блоки отделяла линия, вот так:

Как это сделать? Я что-то не соображу.


Ответ

Это можно сделать с помощью псевдокласса :nth-child и псевдоэлементов :before и :after
#four-blocks { overflow: hidden; width: 580px; } #four-blocks .item { border: 1px #dededc solid; height: 232px; float: left; position: relative; width: 280px; } #four-blocks .item:nth-child(-n + 2) { margin-bottom: 13px; } #four-blocks .item:nth-child(-n + 2):before { content: ''; background: #F2F2F0; height: 1px; position: absolute; bottom: -8px; width: 100%; } #four-blocks .item:nth-child(2n + 1) { margin-right: 13px; } #four-blocks .item:nth-child(2n + 1):after { content: ''; background: #F2F2F0; height: 100%; position: absolute; right: -8px; width: 1px; }


Цикл внутри потока. С++

Здравствуйте!
Используеться стандарт С++11, и библиотека
Есть поток который запускаеться в "фоновом" режиме thread.detach(). внутри етого потока есть функция setWallpaper(bool status) с бесконечным циклом:
setWallpaper(bool status) { if(!status) { MessageBox(NULL, status, L"STOP", MB_OK); } while (status) { PVOID path = getPath(rand() % 8 + 1); SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE); Sleep(min * 1000); } }
Если обратиться к етой функции и передать значение переменной false, то цикл все еще работает, но должна бы завершиться. Почему так не пойму. Подскажете? Как остановить/завершить цикл? Спасибо)


Ответ

Я сделал по своему, вроде работает, мне достаточно :)
status и interval в глобальном скоупе.
Да, знаю что не правильно, но мне сойдёт)
bool status = true; int interval = 1;

void startNewThread(int interval) { thread newThread(setWallpaper, &status, interval); newThread.detach(); };
int setWallpaper(bool *status, int interval) { while (true) { if (*status == false) return 0; wstring path = getPath(); SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (PVOID)path.c_str(), SPIF_UPDATEINIFILE); this_thread::sleep_for(chrono::seconds(interval)); } }
При нажатии на кнопку "stop":
bool *ptrStatus = &status; *ptrStatus = false;

Отправка формы при помощи JS?

Добрый день, хочу поинтересоваться, кто-то делал отправку писем через гугл таблицы? Т.е, проворачивал ли, кто-то вот такую схему "сайт -> гугл таблица -> почта" при помощи js? Или же, можете ли вы, подсказать иной способ отправки форм с сайта, с использованием js?


Ответ

Или же, можете ли вы, подсказать иной способ отправки форм с сайта, с использованием js?
Да, такие варианты есть, например - использовать EmailJS. Другой вариант - использовать JS GMail API. Остальные варианты без труда ищутся по запросу send emails javascript
Добрый день, хочу поинтересоваться, кто-то делал отправку писем через гугл таблицы? Т.е, проворачивал ли, кто-то вот такую схему "сайт -> гугл таблица -> почта" при помощи js?
Именно такая схема не имеет смысла, есть смысл просто параллельно организовать в коде отправку и письма, и лида в GD. Для работы с последним вы также можете найти множество примеров реализации в сети, включая документацию от самого Google

MS SQL SERVER (Ubuntu 16.04.2) Требования

Здравствуйте! Есть некоторый чат-бот(написан на c# с использованием .net core и Entity Framework Core.), который использует в качестве бд MS SQL на MS SQL Server.
Недавно решил залить его на сервер (2.2ГГц, 0.5 RAM, 10 gb hdd), чтобы он не зависел от состояния моего пк и столкнулся с проблемой при установке.
Для установки MS SQL Server требуется минимум 3.25gb ram, хотя при работе он у меня ест не более 200 мб, на серваке же всего 500мб Ram. Более дорогой сервер не потяну.
Посоветуйте, как поступить. Можно ли обойти это ограничение при установке? Или же лучше поменять субд? Если да, то что лучше выбрать? ('легковесное')
P.S EF core вроде поддерживает скажем SQLite и MySQL. Установку проводил по этой инструкции.


Ответ

При размере RAM 500Mb в принципе работа SqlServer невозможна. Вот вам пример, у меня запущен сервер на виртуалке

Кроме сервера ничего более не установлено, а он уже жрет память в таком кол-ве, заметьте без нагрузки и с 5-ю копеечными тестовыми базами.

Как использовать динамическую память в c++?

Как работает динамическая память и какими операторами пользоваться для работы с ней в C++?


Ответ

В С++ объекты создаются динамически при помощи new-выражений и разрушаются при помощи delete-выражений.
T* obj = new T; delete obj;
T* arr = new T[100]; delete[] arr;
New-выражения и delete-выражения используют функции выделения динамической памяти operator new, operator new[] и функции освобождения operator delete, operator delete[] соответственно.
Реализация С++ предоставляет несколько глобальных функций выделения и освобождения. При этом они могут быть переопределены пользователем без нарушения ODR (но не более одного раза в программе).
void* operator new(std::size_t); void operator delete(void*) noexcept; void operator delete(void*, std::size_t) noexcept;
void* operator new[](std::size_t); ...
Пользователь также может добавлять свои функции выделения и освобождения, в виде статических членов класса или свободных функций в глобальном пространстве имен. Такие пользовательские функции должны соблюдать семантику встроенных (не выделять уже выделенные адреса и т.п.).
Выражения new и delete для одного объекта
Функции operator new и operator delete только выделяют и освобождают память. Конструирование и разрушение объекта происходит в самом выражении new и delete. Для вызова конструктора используется new который не выделяет память - размещающий new
// Эквивалент кода // T* obj = new T(a1, a2); T* obj; { void* mem = operator new(sizeof(T)); try { obj = new(mem) T(a1, a2); // Размещающий new, вызывает конструктор T на памяти mem } catch (...) { // Исключение в конструкторе operator delete(mem); throw; } }
// Примерный* эквивалент кода // delete obj; obj->~T(); // Вызов деструктора operator delete(obj);
// *) При виртуальном деструкторе компилятор сгенерирует что-то похожее на void* mem = obj->~T(); // псевдокод operator delete(mem); // Т.к. при множественном наследовании может быть mem != obj
Из кода выше видно, что new-выражение требует обе функции, operator new и operator delete
Функции operator new и operator delete в стандартной библиотеке
Обычный new
void* operator new(std::size_t size);
Использование:
T* p = new T; assert(p != nullptr);
Примерная реализация:
void* operator new(std::size_t size) { for (;;) { void* mem = unspecified_alloc(size); // Может быть malloc, зависит от реализации. if (mem) return mem;
// Пользовательская функция-обработчик нехватки памяти. std::new_handler user_handler_fn = std::get_new_handler(); if (!user_handler_fn) throw std::bad_alloc(); user_handler_fn(); // Либо предоставляет память, // либо бросает bad_alloc или завершает программу. } }
Пользователь может установить свою функцию new_handler при помощи функции std::set_new_handler
Не-бросающий исключений new
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
Использование:
T* p = new(std::nothrow) T; if (!p) { /* не удалось выделить память */ }
Примерная реализация:
void* operator new(std::size_t size, const std::nothrow_t&) noexcept { try { return operator new(size); } catch (const std::bad_alloc&) { return nullptr; } }
Размещающий new
void* operator new(std::size_t size, void* ptr) noexcept { return ptr; }
Ничего не выделяет, возвращают аргумент ptr Позволяют вызвать конструктор объекта.
char mem[sizeof(T)]; T* p = new(mem) T;
Размещающий operator delete также существует, и также ничего не делает. Нужен только потому что new-выражение требудет наличия operator delete
Динамические массивы, new[] и delete[]
Функции operator new[] и operator delete[] служат для выделения памяти, и ничем не отличаются от функций для одного объекта. Стандартные реализации просто вызывают operator new
void* operator new[](std::size_t size) { return operator new(size); }
Размер динамического массива сохраняется самим выражением new[], примерно так:
// Эквивалент кода (без учета выравнивания) // T* arr = new T[100]; T* arr; { void* mem = operator new[](sizeof(std::size_t) + sizeof(T)); std::size_t& size = *reinterpret_cast(mem); arr = reinterpret_cast(reinterpret_cast(mem) + sizeof(std::size_t)); try { for (size = 0; size != 100; ++size) { new(tmp_arr + size) T; // Конструктор элемента } } catch (...) { while (size != 0) { --size; arr[size].~T(); // Деструктор элемента } operator delete[](mem); throw; } }
// Эквивалент кода (без учета выравнивания) // delete[] arr; { std::size_t& size = reinterpret_cast(arr)[-1]; while (size != 0) { --size; arr[size].~T(); // Деструктор элемента } operator delete[](size); }
Массивы созданные при помощи выражения new T[N] могут быть освобождены только через delete[] и наоборот, объекты созданные new T(), должны быть быть освобождены delete
Размещающий new[]
void* operator new[](std::size_t size, void* ptr) noexcept;
Он существует, но мы не знаем сколько байт будут резервироваться копилятором под размер объекта, поэтому не сдедует его использовать:
// char mem[100 * sizeof(T) + sizeof(std::size_t)]; // Компилятор может использовать больше чем sizeof(std::size_t), тогда мы выйдем за границы mem. // new(mem) T[100];

Ruby on Rails Activerecord - id в модели перепутаны

Дело обстоит в Ruby on Rails 4.2.0 на Ruby 2.1.0.
Есть следующая миграция:
class CreateStateTemplates < ActiveRecord::Migration def change create_table :state_templates do |t|
t.string :name
t.references :next t.references :prev
t.timestamps null: false end end end
...такая модель:
class StateTemplate < ActiveRecord::Base
has_one :prev, :class_name => "StateTemplate", :foreign_key => "prev_id" belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "prev_id" has_one :next, :class_name => "StateTemplate", :foreign_key => "next_id" belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "next_id"
end
Если выполнить следующее:
StateTemplate.find(1).update(:next => StateTemplate.find(2)) StateTemplate.find(2).update(:next => StateTemplate.find(3), :prev => StateTemplate.find(1)) StateTemplate.find(3).update(:next => StateTemplate.find(4), :prev => StateTemplate.find(2)) StateTemplate.find(4).update(:next => StateTemplate.find(5), :prev => StateTemplate.find(3)) StateTemplate.find(5).update(:prev => StateTemplate.find(4))
Происходит нечто странное. Получение одного StateTemplate в консоли показывает следующее:
2.1.0 :007 > StateTemplate.find(2) StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]] => #
Что неверно, next_id должен быть 3. При этом метод next показывает следующее:
2.1.0 :008 > StateTemplate.find(2).next StateTemplate Load (0.1ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."id" = ? LIMIT 1 [["id", 2]] StateTemplate Load (0.0ms) SELECT "state_templates".* FROM "state_templates" WHERE "state_templates"."next_id" = ? LIMIT 1 [["next_id", 2]] => #
А это уже верно.
Почему id в записи перепутаны местами, но получение ассоциированных записей при этом работает верно?


Ответ

Потому что вы перепутали has_one и belongs_to. Для обеих сторон.
К тому же, сейчас у вас дважды определена ассоциация state_template, работать будет только последнее из этих определений. Уже это указывает, что что-то с определениями не так.
Посмотрим на next
Проблема тут:
has_one :next, :class_name => "StateTemplate", :foreign_key => "next_id" belongs_to :state_template, :class_name => "StateTemplate", :foreign_key => "next_id"
Это должно быть:
belongs_to :next, :class_name => "StateTemplate"
И симметрично для prev

Что происходит?
Вы, наверное, думаете, что эти две строчки ведут себя примерно одинаково:
StateTemplate.find(1).update(:next => StateTemplate.find(2)) StateTemplate.find(1).update(:next_id => 2)
Но из ваших ассоциаций следует, что первая строчка изменяет второй объект (который в аргументе), ставя ему next_id = 1. Несмотря на то, что обновляете вы, казалось бы, первый.
Вы неправильно определили ассоциацию next
Сейчас ассоциированный — объект, у которого next_id равен id владельца. Ибо has_one А хотели вы наоборот: получить объект, id которого равен next_id владельца. Это belongs_to
Запись, которая хранит в себе ключ ассоциированного объекта, относится к нему через belongs_to. А вот has_one и has_many хранят ключ не "в себе", а в ассоциированных объектах.
"Минус на минус даёт плюс". Апдейты сделали совсем не то, что вы подумали. И поиск ассоциированных записей работает не так, как вы хотите. Но оба пользуются одним определением и в сумме они работают верно: запись определённой записи в next действительно заставляет метод next у этого объекта возвращать эту запись.

Как узнать css свойства по значению

У меня есть значение css, мне с помощью javascript нужно узнать какие свойства использует используют это значение. Например 100px.



Ответ

var element = document.getElementById('ewr'); var arrCss = getComputedStyle(element); for(var i = 0; i < arrCss.length; i++){ var currCssName = arrCss[i]; var currCssValue = arrCss.getPropertyValue(currCssName) if(currCssValue == '100px') console.log(currCssName+': '+currCssValue ); }//for(var i = 0; i < arrCss.length; i++)


вызвать adapter.notifyDataSetChanged() не из главного класса, но обновить главный

В общем сейчас делаю корзину покупок, и при удалении товара столкнулся с проблемой обновления окна, когда товар удален. В главном окне есть код, который принимает инфу:
gvCart=(GridView)findViewById(R.id.gridView_Cart); final List array_dynamic = new ArrayList(); adapterCartBuy=new AdapterCartBuy(Cart.this,array_dynamic); gvCart.setAdapter(adapterCartBuy); String register = "http://wwwwwwwwww/cart"; StringRequest request = new StringRequest(Request.Method.GET, register, new Response.Listener() { @Override public void onResponse(String response) { Log.d(TAG,"response"+ response); try { ObjectMapper mapper_main = new ObjectMapper(); PjCart pjCart = mapper_main.readValue(response, PjCart.class); for (PjCartItemsString pjCartItemsString : pjCart.getData().getItems()){ String image = pjCartItemsString.getImage(); itemCart.setImage(image); array_dynamic.add(itemCart); } Log.d(TAG,"pojCart"+ pjCart); }catch (IOException e){ e.printStackTrace(); }adapterCartBuy.notifyDataSetChanged();
Но вью элементы управления и коннект на удаление информации находится в адаптер окне, ниже:
public class AdapterCartBuy extends BaseAdapter { final String TAG = "mylogs"; private LayoutInflater inflater; private Activity activity; private List items; ImageLoader imageLoader=AppController.getmInstance().getmImageLoader(); public AdapterCartBuy(Activity activity, List items){ this.activity=activity; this.items=items; } @Override public int getCount() { return items.size(); }
@Override public Object getItem(int position) { return items.get(position); }
@Override public long getItemId(int position) { return position; }
@Override public View getView(int position, View convertView, ViewGroup parent) { if(inflater==null){ inflater=(LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } if(convertView ==null){ convertView=inflater.inflate(R.layout.item_cart,null); } if(imageLoader==null) imageLoader=AppController.getmInstance().getmImageLoader(); NetworkImageView imageView= (NetworkImageView) convertView.findViewById(R.id.networkImageView_cart); ImageView del=(ImageView)convertView.findViewById(R.id.imageviewCartDel); final TextView textViewToken=(TextView)convertView.findViewById(R.id.textView_itemcart_token); textViewToken.setVisibility(View.GONE);
final TextView itemId=(TextView)convertView.findViewById(R.id.textView_itemcart_id); itemId.setVisibility(View.GONE); del.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String del = "http://wwwwwwww/cart/"+itemId.getText().toString()+"/del"; StringRequest request = new StringRequest(Request.Method.GET, del, new Response.Listener() { @Override public void onResponse(String response) { Log.d(TAG,"response "+ response); if (response.contains("true")){ ВОТ ТУТ НУЖНО ОБНОВИТЬ АДАПТЕР В ГЛАВНОМ ОКНЕ } }
}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) {
} }) { @Override public Map getHeaders() throws AuthFailureError { Map params = new HashMap(); params.put("Accept", "application/json"); params.put("Authorization", "Bearer "+textViewToken.getText().toString());
return params; }
};AppController.getmInstance().addToRequesQueue(request);
} }); //getting data for row final ItemCart item=items.get(position); imageView.setImageUrl(item.getImage(), imageLoader); textViewToken.setText(item.getToken()); itemId.setText(item.getItem_id());
return convertView; }
Надеюсь проблема понятна, и вопрос стоит в том, как я могу обратиться чтобы обновить адаптер в главном классе через слушатель кнопки в другом, адаптер-классе. Или как можно это по другому, грамотно реализовать и не выдумывать костылей.


Ответ

Ваша проблема в том, что обновляя адаптер вы не изменяете данные, которые он отображает. Сначала измените данные, потом обновляйте адаптер.
if (response.contains("true")){ //ВОТ ТУТ НУЖНО ОБНОВИТЬ АДАПТЕР В ГЛАВНОМ ОКНЕ final ItemCart item=items.get(position); //удаляем элемент из списка данных items.remove(item); //обновляем адаптер notifyDataSetChanged(); }
Скорее всего нужно будет также переопределить equals метод в классе ItemCart

Какой тег лучше использовать что бы добавить SVG изображение?

Object:

Embed:

iframe:

IMG:

background-image:
#image { background-image: url(image.svg); }


Ответ

Лучший тег для svg - это svg! Потому что только так вы в дальнейшем сможете им манипулировать. А вообще все зависит от целей, если просто показать картинку - img, если фоном пустить - то используйте background-image.

Почему обращение к SomeClass.class не вызывает инициализацию класса SomeClass?

Вопрос такой: Почему использование A.class не вызывает инициализацию класса А?
Хотя, учитывая, что подготовка класса к использованию состоит из трёх этапов, на первом из которых создаётся объект Class, и лишь третий из которых -- непосредственная инициализация, вопрос логичнее поставить так Почему вызов Class.forName("test.A"); провоцирует инициализацию класса А? Может сам метод Class.forName(String) создан так, чтобы целиком насильно загружать классы?
package test;
class A { static { System.out.println("A is initialized"); } }
public class Test{ public static void main(String[] args) throws Exception { Class c = A.class; System.out.println("whoa..."); c = Class.forName("test.A"); } }

Expected output: A is initialized whoa...
Real output: whoa... A is initialized


Ответ

В JLS 12.4.1 написано:
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.
Что в переводе:
Вызов некоторых отражающих методов в классе Class и в пакете java.lang.reflect также вызывает инициализацию класса или интерфейса.
А в этой документации для метода forName() класса Class чётко написано:
A call to forName("X") causes the class named X to be initialized.
Что в переводе:
Вызов forName («X») вызывает инициализацию класса с именем X.
Соответственно, всё оказалось верно! Метод Class.forName(String) действительно насильно загрузит класс.

Как реализовать полузакрашенную цифру на css/svg?

Вот такая штука только на svg делается верно ? И как сделать плавное обтекание до половины, в свг слаб :)


Ответ

Например:
svg text { font-family: sans-serif; text-anchor: middle; font-weight: bold; font-size: 70px; fill: url(#fendTestGrad); } #fendTestGrad .start { stop-color: #c2c5cc; } #fendTestGrad .end { stop-color: #8f98a1; } svg { background: linear-gradient(135deg, rgba(73,85,97,1) 0%, rgba(74,88,101,1) 100%); } 60

Найти повторяющиеся элементы и изменить их

Суть задачи:
Найти повторяющиеся элементы в строке и изменить их. А те элементы которые не повторяются тоже изменить.
Например все неповторяющиеся элементы заменить на (, а повторяющиеся на )
Таким образом строка seven, должна превратиться в строку ()()(
's' => '(' // неповторяющийся 'e' => ')' // повторяющийся 'v' => '(' // неповторяющийся 'e' => ')' // повторяющийся 'n' => '(' // неповторяющийся
Я пытался сделать задачу через регулярные выражение - не получилось, опыта в этом нет.
Через два цикла for тоже не получилось. Не могу сделать проверку. Буду рад помощи.


Ответ

Спасибо Алексею за наводку как решить задачу. Собственно выкладываю само решение задачи
function duplicateEncode(word){ word = word.toLowerCase().split(""); var key = {}, result = ""; for (var i = 0; i < word.length; i++) { if (key[word[i]] == undefined) key[word[i]] = 1; else key[word[i]]++ } for (var k = 0; k < word.length; k++) { if (key[word[k]] == 1) result += "(" ; else result += ")"; } return result }
P.S. А вот как решили задачу "большие" дяди.
function duplicateEncode(word){ return word .toLowerCase() .split('') .map( function (a, i, w) { return w.indexOf(a) == w.lastIndexOf(a) ? '(' : ')' }) .join(''); }
Вариант с регулярным выражением
function duplicateEncode(word) { word = word.toLowerCase(); return word.replace(/./g, m => word.indexOf(m) == word.lastIndexOf(m) ? '(' : ')'); }

Почему нельзя сложить в C# byte + byte?

Я знаю что нужно выполнить преобразование типов, но хотел бы разобраться в механизме. Почему этот код выдает ошибку?
byte a = 2;
byte b = a + 2; // ошибка


Ответ

Дело в том, что операции с байтами возвращают в результате int. Это не совсем очевидно на первый взгляд, но имеет смысл. Дело в том, что byte - довольно маленькая величина (от 0 до 255), и во многих случаях в результате арифметических операций с двумя байтовыми переменными, возникает переполнение, благодаря чему результат не поместился бы в переменную типа byte. Это явно не очень ожидаемое поведение (например при сложении 200 и 60 получилось бы не 260, ка можно было бы ожидать, а 4), поэтому было решено, что byte + byte = int

Интерфейсы в MVP

Это наверное тысячный вопрос по MVP. Перечитал очень много статей, пересмотрел многие исходники из GitHub. Но мне до сих пор не понятны некоторые вещи. И исходя из одного примера погрузился в MVP, уже не помню название туториала. Но не в этом суть.
Вот пример где практикую с MVP. Структура такова:

Где IChatsInteractor.java:
public interface IChatsInteractor { void getChatsByCount(int count, IChatsCallback chatsCallback);
interface IChatsCallback{ void onSuccess(ChatsModel chatsModel);
void onFailure(String errorMessage); } }
А ChatsInteractorImpl реализовывает IChatsInteractor и подтягивает данные с сервера. Полученные данные записывает в RealmDB и возвращает полученные данные в методе ichatsCallback.onSuccess, ichatsCallback.onFailure если ошибка.
Работает все это корректно. Но проблема в том, что я даже понятия не имею что вообще значит слово interactor (из урока начал использовать). Хочу переименовать, но никак не пойму как, на какое название и т.д.
Вопросы:
Правильно ли то, что из за одного Activity (ChatsActivity) создал 5 классов: (ChatsView - он нужен, понимаю, ChatsInteractorImpl - работает с сервером.) Остальные 3 класса нельзя ли как то объединить или так правильно? Как видите для интеракторов создал отдельный пакет. Можно ли его запихнуть в папку model? Как правильно переименовать интеракторов на название основываясь на его функции? Стоить ли вытаскивать функцию записи полученных данных в базу данных из метода getChatsByCount() в классе ChatsInteractorImpl? И вообще, правильно ли я структурировал (спроектировал) весь MVP, то есть классы, методы?


Ответ

Очень спорный вопрос, нет, это не значит, что он плох, даже наоборот - откровенно всё пишите. По вопросом, мне кажется понимаете правильно, я просто немного попытаюсь помочь. Я люблю вопросы по архитектуре, потому что даже Google колбасит, а различий множество MVP, MVI, MVB, MVVM, MVVSP, VIPER... Не говоря, о том что популярность некоторых полностью или частично меняет структурные решения. Но самое интересное, что действительно каждому, есть место быть, если разработчик считает, что это действительно удобно, во всех направлениях.
Если у вас всё хорошо помещалось в 1 activity, вы легко тестировали этот компонент и легко добавляли новые фичи или даже они не нужны в будущем, то возможно вы излишне использовали MVP. Да, именно так!, я видел множество мелких проектов, которые писали под разные решения, состоящие из несколько простых activity, и действительно тот же MVP там смотрится ужасно. Но! для больших проектов в activity могут использоваться и больше кол-во классов, десятки и сотни и так далее. Вот тогда это будет вашим спасением и во время добавления фичи, вы будете чувствовать себя комфортно, а сторонние разработчики намного быстрей смогут понять идею и приступить к помощи. Объединить можно...., например обернуть фасадом интерфейсы и это смотрится хорошо и редактирование удобное для MVP Действительно интеракторы совмещают с моделью, но тогда модель быстро раздувается, и становится сложно тестируемой и заменяемой. Сейчас есть решения для таких ситуаций и это наверное отдельная тема. Dagger 2 к примеру с Rx, делает эту прослойку незаметной. Если и всё-таки решили так сделать, то модель должна предоставить необходимые данные а вот сама функция, как и всегда по codeStyle должна - быть говорящей. Нет, интеракторы являются посредниками между P и M , и это его задача осуществить нужный запрос от необходимых менеджеров, для получения или записи данных в модель и оповещать presenter о действиях, но это суть, на практике очень сильно бывает размыта. Возможно. По package и нескольким классам тяжело сказать.
UPDATE:
Сразу не увидел link на GitHub, что я могу добавить. Структуруа нормальная, хотя мне кажется MVP уже так мало кто использует, такой примитивный вариант, голый я бы сказал, хотя для понимания так и должно происходить. А вот используете, а точней не используете MVP, рассмотрим на примере LoginActivity.
@Override protected void onStart() { super.onStart(); Realm realm = Realm.getDefaultInstance(); RealmResults accessDM = realm.where(AccessDataModel.class).findAll();
if (accessDM != null) { AccessDataModel accessDataModel = accessDM.get(0); final String string = accessDataModel.getAccessToken() + "
" + accessDataModel.getUserId() + "
" + accessDataModel.getExpiresIn();
Intent intent = new Intent(this, ChatsActivity.class); intent.putExtra("data", string).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); }
realm.close(); }
CodeStyle упустим. Самое плохое, что вы смешали бизнес логику с View, не смотря на то что вы построили MVP, вы продолжаете все делать в Activity. Давайте рассмотирм один вариант на вашем примере: LifeCycle метод onStart() очень показательный. #109 line number
Кратко. Вы берете instance Realm, проверяете какие-то данные на доступ, если данные есть - формируете String и переходите в ChatActivity. Как примерно должно быть: Когда срабатывает onStart Activity() вы просто сообщаете презентору об этом. И ваш метод должен выглядеть примерно так:
@Override protected void onStart() { super.onStart(); mPresenter.onActivityStarted(); }
Замечу, что плохим тонном считается дублировать колбеки жизенного цикла компонентов 1 в 1:
Плохо:
@Override protected void onDestroy() { presenter.onDestroy(); super.onDestroy(); }
они должны для презенторов нести логику, но также нужно сходу отличать название, ибо когда другой компонент будет вызвать аналогичный метод или Fragment, вам придется не только переименовать, но и переходить внутрь, чтоб понять, что куда. Более того заметьте что вы вызываете презентер перед супер методом, тоже сомнительно, ибо если есть базовые классы или измененные State, может полвиять на логику работу в презентере то можете словить Leak.
в Presenter должно быть примерно так:
@Override public void onActivityStarted() { boolean ifAccess = getInteractor.getAccess(); if (ifAccess) getMvpView().navigateToChatsActivity(getInteractor.getAccessToken); else getMvpView().showAccessDenied(); }
во View если доступ есть:
@Override public void navigateToChatsActivity(String accessToken) { Intent intent = new Intent(this, ChatsActivity.class); intent.putExtra("data", accessToken).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); }
если нет:
@Override public void showAccessDenied() { Toast.makeText(this, "AccessDenied", Toast.LENGTH_LONG).show(); }
А интерактор разбирается с instance realm, и выполняент работу асинхронно. У меня в примере, более примитивно, чтоб вы уловили суть MVP, особенно если вы не работаете c Rx.

Удалить ненужные коммиты

Есть вот такой перечень коммитов.
коммит 5 коммит 4 коммит 3 коммит 2 коммит 1
Хочу удалить коммиты 5, 3 и 2. Т.е не просто убрать их видимость в ветке, а удалить насовсем. Можно ли это сделать с сохранением коммита 4?


Ответ

Для подобного действия Вам нужен интерактивный rebase. Если кратко, тогда так
вначале нужно его запустить
git rebase -i HEAD~6
Вместо HEAD~6 (шесть коммитов назад), можете взять хеш любого коммита перед коммитом 1. Откроется вим или другой редактор. Там будет список коммитов. Теперь удаляем ненужные коммиты (просто удаляем строки). Если это вим, тогда просто нажимаем дважды d на нужных строках (то есть тех, которых нужно удалить).
Потом выходим с редактора (если это вим - Esc wq).
После этого git откатит эти коммиты и накатит их по новому. Вполне возможно, что нужно будет по ходу дела решать конфликты.
Помните, что на самом деле старые коммиты никуда не уйдут, просто будут созданы новые коммиты.
Если эти коммиты уже были запушены на удаленный сервер, то лучше не делать подобного. Но если над проектом работаете только Вы, то нет ничего страшного. Но пуш придется делать форсированным (-f).

Папка .vs весит слишком много Visual Studio 2017

На сколько я знаю, папка ".vs" предназначена для хранения пользовательских настроек проэкта. Раньше, на Visual Studio 2015 такая папка весила до 10мб, но стоило мне обновится до 2017 вижуалки и объем папки (в том же самом проекте) стал занимать более 400 мб. И так во всех других проектах. Даже если создать полностью чистый проэкт, то папка .vs уже весит до 20 мб.
Вопрос состоит в следующем: Если это баг, то как исправить? Если это не баг, то существует ли возможность настроить объем данной папки?


Ответ

У вас в папке .vs складируется база intellisense. Это можно отключить выставив в настройках студии на вкладке Text Editor -> C/C++ -> Advanced -> Fallback Location опцию Always use Fallback Location на True и опцию Do not Warn If Fallback Location Used на True. В этой группе еще есть третья опция, позволяющая задавать конкретное расположение для этих данных (по-умолчанию они попадают в temp кажется). После этого следует закрыть студию (все) и удалить папку .vs. При следующем запуске студия заново создаст базу для intellisense в новом расположении, а в папке .vs будет только маленький файл .suo. Кроме того, при добавлении в репозиторий папку .vs следует исключать в любом случае.

Рисование в консоли Visual Studio c++

Учился писать код в паскале. По ходу учебы перешел на с++ и Visual Studio. В борланд паскале был удобный канвас в котором можно было рисовать фигуры/графики функций etc. есть ли в visual studio аналог?


Ответ

В Windows на окне можно рисовать средствами GDI, консольное окно не исключение. Естественно такое решение будет непереносимым. Пример:
#include #include #include
int main() { HWND hwnd = GetConsoleWindow(); HDC hdc = GetDC(hwnd);
int x = 0; for (float i = 0; i < 3.14 * 10; i += 0.05) { SetPixel(hdc, x, 50 + 25 * cos(i), RGB(255, 255, 255)); x += 1; }
ReleaseDC(hwnd, hdc); std::cin.ignore(); return 0; }
Результат:

Кроме установки пикселя в наличии большое кол-во функций для рисования различных примитивов, с применением разных кистей (толщины, узора и т.п.).
Внимание! Работает сносно только в старых версиях Windows (Windows XP). Не использовать для современных систем, начиная с Vista.

Передача выборки в процедуру Oracle?

Никак не разберусь с вопросом. Структура процедуры:
CREATE OR REPLACE PROCEDURE <Имя_процедуры> ( <переменная_1> IN <тип_переменной_1>, ... ) AS <внутренняя_переменная_1> <тип_внутренней_переменной_1>; ... BEGIN <Тело на языке SQL>; END; /
Но что если я хочу подать в переменную какую-то выборку? Например, если у меня есть временная таблица и передать всю таблицу как переменную из которой в теле процедуры можно было бы делать какие-то выборки.


Ответ

Попробуйте так:
create or replace type itemRow as object (id number, name varchar2 (32)); / create or replace type itemRows is table of itemRow; /
create or replace function passonItems (resultSet sys_refcursor) return itemRows pipelined is item itemRow; begin <> loop fetch resultSet into item; exit processResultSet when resultSet%notfound; -- здесь требуемая логика pipe row (item); end loop processResultSet; close resultSet; return; end; /
select * from table ( passonItems ( cursor (select itemRow(level, 'item '||level) from dual connect by level<4) ) );
ID NAME ---------- -------------------------------- 1 item 1 2 item 2 3 item 3
Функция пока ничего не делает, только пропускает 1:1 данные через себя.

Изменение поля description в gitweb

В gitweb в поле description проекта следующее описание:
Unnamed repository; edit this file 'description' to name the repository.
И я хочу изменить это описание проекта. В своём локальном репозитории я изменила файл .git\description, но как передать эти изменения на удалённый репозиторий?


Ответ

В большинстве случаев, никак. Файл .git\description автоматически не синхронизируется с удалённым репозиторием.
На сервере создаётся обычно так называемый bare (пустой, не содержащий рабочей копии) репозиторий. В gitweb колонкa |Project| выглядит в этом случае, например так: myproject.git.
Изменить описание проекта можно прямо на сервере, где лежит удалённый репозиторий, отредактировав первую строчку файла: /repos_root_path/myproject.git/description

gitweb is not interested in a working area, and is best suited to showing "bare" repositories
Gitweb первоночально создавался для bare репозиториев и файл description используется только в нём, больше нигде. Как следствие, синхронизация этого файла не была предусмотрена.
В актуальной версии gitweb также работает с non-bare репозиториями, то есть содержащими рабочие копии. Колонкa |Project| в gitweb будет выглядеть тогда, например так: myproject/.git (со слешем).
В этом случае, воспользуйтесь уже опубликованным рабочим решением в ответе от @NickVolynkin. Можно также ознакомиться здесь и перейти в принятом ответе по ссылке для аналогичного решения.
Подробности в документации

C++ Корневая (текущая) папка программы (указать)

С++ Как задать корневую (текущую) папку для программы, например у меня есть параграмма с файлами картинками (ресурсы программы), но если я откраиваю файл с помощью этой параграммы, программа не находит своих файлов (ресурсов). в итоге Корневая (текущая) директория устанавливается в папке с открытым файлом. А если я просто открываю программу Корневая (текущая) директория устанавливается в папке с программой, и все ресурсы загружаются отлично.
Использую visual studio 2010 ОС: windows 10 x86
Ответ что я ожыдал функцыя устанавлевает корневую папку SetCurrentDirectory("Путь к корневой папке програмы");


Ответ

Рабочий каталог используется для поиска файлов, заданных с помощью относительного пути
Текущая директория наследуется программой от её родителя. К примеру, если запустить в командной строке, то по умолчанию программа будет искать файлы относительно текущего пути в командной строчке (pwd, echo %cd%).
Если вы запускаете программу вне папки с картинками, то в настройках передайте необходимый путь (в конфигурационном файле, в переменных окружения, в опциях командной строки) и используйте абсолютные пути для открытия файлов (переданный путь + относительный путь). Вот пример, где используется либо путь, заданный в командной строке, либо текущий путь, если не задан путь:
fs::path dirpath = (argc == 2) ? argv[1] : fs::current_path();
Чтобы объединить переданный путь и относительный путь: path = dirpath / relpath
Выражение "корневая директория" не имеет отношения к текущей директории (к примеру, chroot(2) vs. chdir(2)).

Процесс загрузки динамической библиотеки под Linux и Windows

Есть динамическая библиотека в которой определена глобальная переменная. Также определена функция DllMain Которая использует эту глобальную переменную:
std::string g_value("value");
//Windows BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) { //использование g_value; }
//Linux void start() __attribute__ ((constructor)); void start() { //использование g_value; }
Под Windows сначала инициализируются глобальные переменные а потом уже начинает выполнятся DllMain (это всегда так или порядок не определен строго?). Под Linux наоборот сначала выполняется start, а потом глобальные переменные.
Можно ли задать порядок выполнения? Сначала глобальные переменные а потом start?


Ответ

Нужно задать порядок инициализации:
std::string g_value __attribute__((init_priority(101))) = "value";
void start() __attribute__((constructor(102)));
void start() { // использование g_value; }
Решение взято отсюда:
Bug 52477 - Wrong initialization order? __attribute__((constructor)) vs static data access
По результатам обсуждения бага, была дополнена документация (6.31.1 Common Function Attributes) и сказано, что для С++ порядок инициализации глобальных данных и функций с атрибутом constructor не определён и рекомендуется использовать атрибут init_priority
The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () completes or exit () is called. Functions with these attributes are useful for initializing data that is used implicitly during the execution of the program. You may provide an optional integer priority to control the order in which constructor and destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger priority number; the opposite relationship holds for destructors. So, if you have a constructor that allocates a resource and a destructor that deallocates the same resource, both functions typically have the same priority. The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes). However, at present, the order in which constructors for C++ objects with static storage duration and functions decorated with attribute constructor are invoked is unspecified. In mixed declarations, attribute init_priority can be used to impose a specific ordering.

numpy выдаёт nan для corrcoeff

Не пойму, почему numpy отдаёт nan. Если есть два разных массива, то вылетают nan
np.corrcoef([0.1, 0.1, 0.1], [0.9, 0.9, 0.9]) array([[ 1., nan], [ nan, nan]])
При этом, если два одинаковых массива, то этого не происходит:
np.corrcoef([0.1, 0.1, 0.1], [0.1, 0.1, 0.1]) array([[ 1., 1.], [ 1., 1.]])
Также непонятно, почему corrcoef отдаёт все nan для нулей:
np.corrcoef([0, 0, 0], [0.1, 0.1, 0.1]) array([[ nan, nan], [ nan, nan]])


Ответ

Если смоделировать то что происходит внутри функции np.corrcoef()
In [37]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9]
# расчет ковариционной матрицы In [38]: c = np.cov(x,y)
# для указанных значений - она имеет нулевые значения для 3-х из 4-х элементов # в результате `np.corrcoef()` на месте этих элементов будут стоять NaN In [39]: c Out[39]: array([[ 2.88889492e-34, 0.00000000e+00], [ 0.00000000e+00, 0.00000000e+00]])
In [40]: d = np.diag(c)
In [41]: d Out[41]: array([ 2.88889492e-34, 0.00000000e+00])
In [42]: stddev = np.sqrt(d.real)
In [43]: stddev Out[43]: array([ 1.69967494e-17, 0.00000000e+00])
В следующей строке мы получим NaN как результат деления на ноль:
In [44]: c /= stddev[:, None] ...\py36\Scripts\ipython3:1: RuntimeWarning: invalid value encountered in true_divide
In [45]: stddev[:, None] Out[45]: array([[ 1.69967494e-17], [ 0.00000000e+00]])
In [46]: c Out[46]: array([[ 1.69967494e-17, 0.00000000e+00], [ nan, nan]])
Как это обойти - прибавить очень маленькое число к одному или нескольким элементам второго массива:
In [109]: x=[0.1, 0.1, 0.1]; y=[0.9,0.9,0.9+1e-16]
In [110]: np.corrcoef(x,y) Out[110]: array([[ 1. , -0.57735027], [-0.57735027, 1. ]])
или
In [111]: x=np.array([0.1, 0.1, 0.1]); y=np.array([0.9,0.9,0.9])+1e-16
In [112]: np.corrcoef(x,y) Out[112]: array([[ 1., -1.], [-1., 1.]])

Сайт это тоже API?

Гуглил о том что такое API, и везде примеры сводятся к тому, что вот есть сайт и к нему можно приделать API чтобы другие приложения могли взаимодействовать с сайтом. Но никто не пишет о том, является ли API сам сайт, когда клиент из браузера отправляет к нему запрос. Ведь по сути когда я в браузере открываю сайт example.com то, сам браузер обращается к API сайта и получает text/html ответ т.е. получается взаимодействие двух приложений.
Так вот вопрос: Сайты это тоже API для взаимодействия между браузером и сервером? (не совсем корректно сформулированный вопрос, но надеюсь смысл понятен)


Ответ

Сложность вопроса в том, что термин API весьма всеобъемлющий и не очень чёткий.
Ответ сильно зависит от контекста.
С чисто теоретической точки зрения да, можно считать и так. Пользователь всё-таки не может взаимодействовать с сайтом сколько-нибудь напрямую. Посему, можно считать, что сайт как множество допустимых HTTP-запросов к нему, это API между сервисом, который он предоставляет, и браузером. Причём поскольку в ответах API описываются возможные запросы, он ещё и, в некотором смысле, самодокументируемый. Это круто.
В реальном коде сервис и его "браузерный API" (называемый иногда "веб-интерфейсом") могут быть практически неразделимы. Обычно это плохо. Но может быть простительно, если других интерфейсов не ожидается, и/или если сервис сам по себе является интерфейсом к чему-то ещё.
Но если рассуждать так и далее, то и выполняемые вами (человеком; вы же человек?) действия с браузером происходят через API: интерфейсы ввода-вывода ОС. Тут, впрочем, API уже заканчиваются и начинается аппаратный интерфейс.
Но это с вашей позиции. Существуют также программно управляемые браузеры (был специализированный PhantomJS, сейчас это штатно существует и в Chrome, есть и другие), которые для серверов очень похожи на обычных пользователей. Для управляющих ими программ множество возможных запросов к сайту является API в самом прямом смысле: программа взаимодействует через этот интерфейс с приложением.

А на практике, в веб-разработке обычно считается, что браузер — пользователь. То, что за ним ещё какие-то интерфейсы, уже не в её области. И там принято разбивать HTTP-сервисы на две группы:
сайты: с которыми браузеры взаимодействуют более-менее напрямую, без дополнительных механизмов API: с которыми напрямую взаимодействуют другие приложения, самостоятельные (автоматизация действий штатными способами или взаимодействие между сервисами) или SPA (запускаемые из кода, доставленного сайтом)

Что использовать var или let

Вот думаю что лучше использовать внутри функций, var или let?
Так как я использую компиляцию TypeScript то с поддержкой старых браузеров проблемы быть не должно в обоих вариантах.
Как я понял let более предпочтительный, так как он полностью локален в блоках и более предсказуем.
Но меня смущает использование let в циклах, так как для каждой итерации создаётся своя переменная. Зачем это делается я знаю, но беспокоюсь за съедание лишней памяти. Или это такая мелочь для большинства задач, что на эту тему париться не стоит? Ответы прошу аргументированные.
PS: это не дубликат вопроса "Отличие let/const от var" потому что тот вопрос про конкретную ошибку в коде, а мой вопрос теоретический и более общий про использование данных конструкций. Кроме того я не спрашиваю про отличая, их я знаю, меня интересует что предпочтительнее использовать.


Ответ

Напишу свой взгляд на let и var
Конечно, let - некий "новый синтаксический сахар". С ним могут возникать проблемы совместимости, но если это для вас не особо важно, то я бы использовал именно let. Мои аргументы:
Приведенная выше конструкция мне кажется просто ужасной:
if (true) { var a = 2; }
a = a + 2;
В основном, с точки зрения читаемости. Человек, читающий ваш код, может часами искать объявление этой переменной. А раз эта конструкция ужасна, то единственное преимущество var - фигня. Что касается циклов. Конечно, создается новая переменная... Но тогда, когда эта переменная уже не нужна, любой нормальный GC ее соберет. С той же var если вам нужно было сделать коллбэки в цикле, нужно было использовать дополнительную функцию, чтобы создать копию переменной. Что еще хуже.
Ну, пока что это все, что приходит на ум, но мне кажется, что этих причин достаточно. Единственное, на что вам нужно смотреть при выборе let или var - могут ли быть проблемы с совместимостью. Если нет - то смело используйте let

Что делает конструкция (obj.f = obj.f)() и почему при ее использовании теряется контекст вызова? [дубликат]

На данный вопрос уже ответили: Потеря контекста вызова 5 ответов Не могу понять роль нуля в данном контексте. JS 1 ответ function foo() { return this; }
let bar = { foo };
console.log( foo(),
bar.foo(), (bar.foo)(),
(bar.foo = bar.foo)(), // здесь );
Собственно, понятно, почему bar.foo() вернет bar. Почему (bar.foo)() вернет bar - тоже. А вот почему теряется контекст в последнем выражении - вообще непонятно.
Непонятно также, что делает такая конструкция. Что она в конечном итоге вызывает? Левый операнд или правый? (Понятно, что в данном конкретном случае разницы нет, но я говорю про общий случай).


Ответ

foo() - вызов функции в глобальном контексте (тут все просто)
bar.foo() - вызов метода объекта bar - JS создал для вас ключи у объекта (вообще так создавать объекты не есть хорошо, но JS решил что это должно выглядеть так {foo: foo, baz: baz}). См. короткая нотация
(bar.foo)() - то же самое что и в прошлом случае
(bar.foo = bar.foo)() - тут интереснее - мы вызываем не метод объекта, а глобальную функцию, которая является результатом выражения в скобках. То есть мы берем значение поля - которое является функцией и присваиваем другому полю (в данном случае они одинаковые), но результатом будет именно эта функция а не поле (поскольку последней операцией в скобках было присваивание, а не разыменование метода)
Дополнение
Если выполнить пример в строгом режиме - при потере контекста получим undefined. См this в контексте функции

Что нужно для написания приложения на Android?

Меня интересует инструментарий для создания приложения на Android. С чем придется столкнуться, какой язык нужно учить? Т.е., нужно разработать приложения на Android. Что для этого нужно?


Ответ

Установить на компьютер Андроид студио - это среда разработки. Зная свой проект (задачу), можно приступать шаг за шагом делать UI (верстать видимую часть приложения). В этом помогут уроки по юдасити (на анг, есть ру субтитры).
Второй момент - изучение Java. Знание Java поможет быстро освоить Kotlin - более модернизированный язык.
Третий момент - отдельные аспекты в программировании (RxJava - многопоточность; чистая архитектура и др).
По опыту, сталкиваясь с задачей, я обретаю нужный мне запас инструментов, который постепенно расширяю. Сразу все читать/изучать - слишком запутанно будет. Держать баланс: теория - практика.
Вывод: рекомендую уроки https://www.udacity.com/
затем переходить на уроки Java https://metanit.com/java/tutorial/
Все это практиковать по отношению к своему проекту.

с css что-то не так или все в порядке?

при просмотре исходного кода страницы (и результата просмотра http в гугл-консоли) заметил, что все ссылки заканчиваются странным образом, пример: