Страницы

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

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

Где можно получить список городов России для приложения

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


Ответ

Вообщем использовал Google Places Api, получилось лучше чем я думал.

Зависит ли время на создание объекта от количества его свойств и методов?

Есть 2 класса:
public class MyClass { public int Prop { get; set; } }
public class MyClass2 { public int Prop1 { get; set; } public int Prop2 { get; set; } public int Prop3 { get; set; } public int Prop4 { get; set; } public int Prop5 { get; set; } }
Конструкторы этих классов отработают за одинаковое количество времени или нет?


Ответ

Исследования показали, что время выполнения конструктора зависит от количества памяти, выделяемой под экземпляр класса. Соответственно, поля и свойства с неявными get/set (как у вас) влияют, а методы и свойства с явными get/set не влияют (память под них в экземпляре не выделяется).
using System; using System.Collections.Generic; using System.Diagnostics;
namespace ConsoleTest {
public class LittleClass { public int Prop0 { get; set; } }
public class BigClass { public int Prop1 { get; set; } public int Prop2 { get; set; } public int Prop3 { get; set; } public int Prop4 { get; set; } public int Prop5 { get; set; } }

class Program { const int N = 100000000;
static void Main(string[] args) { Stopwatch s; int i;
LittleClass lc = new LittleClass(); BigClass bc = new BigClass();
/* ------------------------------------------------------------------*/ s = new Stopwatch(); Console.WriteLine("BigClass test..."); s.Start(); for (i = 0; i < N; i++) { bc = new BigClass(); } s.Stop(); Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString()); /* ------------------------------------------------------------------*/ s = new Stopwatch(); Console.WriteLine("LittleClass test..."); s.Start(); for (i = 0; i < N; i++) { lc = new LittleClass(); } s.Stop(); Console.WriteLine("t=" + s.ElapsedMilliseconds.ToString()); /* ------------------------------------------------------------------*/ Console.ReadKey(); } }
}
Результат (оптимизация включена)

По моим расчетам, время инициализации класса описывается формулой
t=(2,6*s+43,8)/(10^7) мс
где s - суммарный размер типов всех членов, под которые память выделяется (см.выше),
с коэффициентом корелляции 0,99.
Наличие постоянной составляющей, я полагаю, объясняется наличие служебной информации, под которую выделяется, предположительно, 16 байт.

Исследование проводилось на машине с процессором с тактовой частотой 2.33 ГГц. Для вычисления времени, не зависимого от машины, надо эту формулу умножить на тактовую частоту, получая время в "тактах процессора":
t = 0,6*s+10,9

Доступ к элементам MainWindow из статического класса

Подскажите, пожалуйста, как обратиться к TextBox'у с именем textBox1, размещенному в MainWindow, из метода статического класса SomeStaticClass?
namespace Programm1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } }
public static class SomeStaticClass { public static void Test() { MainWindow.textBox1.Text = "Done!"; // Ошибка } } }
Ошибка:
Для нестатического поля, метода или свойства требуется ссылка на экземпляр.


Ответ

Сделать статическую переменную Instance в которой будет форма и обращаться к ней.
public partial class MainWindow : Window { public static MainWindow Instance { get; private set; } // тут будет форма
public MainWindow() { InitializeComponent(); Instance = this; // инициализируем статическую переменную } }
public static class SomeStaticClass { public static void Test() { if (MainWindow.Instance != null) // обращаемся к ней из статического класса/метода MainWindow.Instance.textBox1.Text = "Done!"; } }
Возможно, подход не самый правильный, но достаточно простой и понятный.

Предложу еще более простой вариант. Переписать статический метод, чтобы он принимал компонент TextBox и менял его свойство, вот так:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); SomeStaticClass.Test(this.TextBox); // передаем наш TextBox в метод } }
public static class SomeStaticClass { public static void Test(TextBox textBox) // принимаем наш компонент { if (textBox != null) textBox.Text = "Done!"; // меняем его значение } }
В этом подходе никаких статических переменных, просто добавлен параметр в метод.

Как реализовать автоматическое выпадающее меню?

Добрый день! Подскажите, пожалуйста, реализацию, при которой бы при уменьшении экрана ссылки, которые не помещаются в одну строку, автоматически складывались бы в выпадающее меню. Благодарю за помощь!
.header-item { padding: 7px 0; } .hi { display: inline-block; } .hi:after { content: '|'; margin: 0 17px 0; display: inline-block; color: #ccc; vertical-align: middle; }


Уточняю вопрос: при уменьшении экрана необходимо, чтобы не все сразу ссылки помещались в выпадающее меню, а поочередно, по мере их выхода за пределы видимости экрана. спасибо!


Ответ

Первым делом напишем необходимый CSS: добавим всем элементам white-space: nowrap, чтобы они не переносились на следующую строку; скроем меню по правилам доступности — это нам также потребуется в дальнейшем при расчетах ширины скрытых элементов. При нажатии на кнопку будем отображать и скрывать меню с элементами, которые не поместились в список. Функция getInvisible() возвращает нам массив элементов, которые не помещаются в ширину списка. Основа всех расчетов — метод .getBoundingClientRect() Функция moveForward() переносит все не помещающиеся элементы в выпадающее меню. Функция moveBackward() переносит элементы из выпадающего меню обратно — это нам потребуется при ресайзе окна. Функция debounce() нужна для оптимизации вызова функции при ресайзе. Добавляем слушателя на событие ресайза и вызываем функцию restart(), которая вызывает moveBackward() и moveForward(). Таким образом, при ресайзе все элементы возвращаются обратно в строку, а затем те, которые не помещаются отправляются обратно в выпадающий список.
UPD. добавил также подсчет количества скрытых элементов и скрытие кнопки, когда все элементы меню видны.
let button = document.getElementById('menu-toggler'); button.addEventListener('click', function() { document.querySelector('.menu').classList.toggle('menu--open'); }); window.addEventListener('resize', debounce(restart, 250)); moveForward(); function moveForward() { let listElements = Array.from(document.querySelectorAll('#list .li')), invisibleElements = getInvisible(listElements), menuList = document.getElementById('menu-list'); invisibleElements.forEach(function(item) { menuList.appendChild(item); }); if(!invisibleElements.length) { button.setAttribute('hidden', true); } else { button.removeAttribute('hidden'); } button.innerHTML = invisibleElements.length; } function moveBackward() { let menuListElements = Array.from(document.querySelectorAll('#menu-list .li')), list = document.getElementById('list'); menuListElements.forEach(function(item) { list.appendChild(item); }); } function restart() { moveBackward(); moveForward(); } function getInvisible(listElements) { let list = document.getElementById('list'); let invisible = listElements.filter(function(item) { if (item.getBoundingClientRect().left + item.getBoundingClientRect().width > list.clientWidth) { return item; } }); return invisible; } function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; #menu-toggler { position: absolute; right: 8px; top: 8px; width: 35px; height: 35px; } #list { width: calc(100% - 100px); padding: 0; margin: 0; white-space: nowrap; border: 1px solid #000; font-size: 0; overflow: hidden; } #menu-list { margin: 0; padding: 0; } .li { display: inline-block; padding: 5px 10px; font-size: 16px; } .menu { border: 1px solid; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; right: 8px; top: 50px; } .menu--open { clip: auto; height: auto; margin: 0; overflow: visible; width: 150px; }

  • element #1
  • element #2
  • element #3
  • element #4
  • element #5
  • element #6
  • element #7
  • element #8
  • element #9
  • element #10
  • element #11
  • element #12
  • element #13
  • element #14
  • element #15
  • element #16
  • element #17
  • element #18
  • element #19
  • element #20

Можно ли методы класса выносить в разные файлы

Иногда класс содержит большое количество методов, свойств и прочего. Хотелось бы как-то это дело сделать более читаемым. На текущий момент пользуюсь
#region реализация интерфейса блаблабла //Какой-то перечень методов #endregion
На мой взгляд было бы удобно, если бы некоторые методы можно было вынести в отдельный .cs файл.
Есть ли такая возможность?


Ответ

Разумеется можно. Для этого существует модификатор класса partial. Пример использования из документации
public partial class Employee { public void DoWork() { } }
public partial class Employee { public void GoToLunch() { } }
Активно используется визуальным дизайнером студии для разделения пользовательского кода разработчика и кода, генерируемого самим дизайнером.

Как сгенерировать изображение в Python?

Я могу загрузить изображение и вывести его на экран следующим образом:
import cv2 img = cv2.imread("1.jpg") cv2.imshow("Original", img)
К примеру, чтобы получить белое изображение, я могу загрузить любое, нарисовать поверх него белый прямоугольник и вывести на экран.
Однако что делать, если я хочу получить белое изображение без предварительной загрузки? Как заменить операцию загрузки операцией генерации объекта-изображения?


Ответ

Код ниже полностью взят из документации
import numpy as np import cv2
# Create a black image img = np.zeros((512,512,3), np.uint8)
# Draw a diagonal blue line with thickness of 5 px cv2.line(img,(0,0),(511,511),(255,0,0),5)
cv2.rectangle(img,(384,0),(510,128),(0,255,0),3) cv2.circle(img,(447,63), 63, (0,0,255), -1) cv2.ellipse(img,(256,256),(100,50),0,0,180,255,-1)
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32) pts = pts.reshape((-1,1,2)) cv2.polylines(img,[pts],True,(0,255,255))
font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)
cv2.imshow("Image", img) cv2.waitKey(10000)
Свеже-сделанный скриншот:

Как получить строку из нескольких повторений слова?

Есть слово: string str = "text"; Как задать 20 повторений этого слова, то есть чтобы слово "text" было написано 20 раз подряд? "texttexttext..." и так 20 раз.


Ответ

Для этого можно воспользоваться StringBuilder-ом и обычным циклом for от 0 до 19 (включительно):
StringBuilder sb = new StringBuilder(); string str = "text"; for (int i = 0; i < 20; i++) { sb.Append(str); } string result = sb.ToString();

Есть вариант покороче с использованием Enumerable.Repeat и string.Concat
string result = string.Concat(Enumerable.Repeat(str, 20));

Асинхронные HTTP-вызовы grequests

Всегда использовал библиотеку requests. Но как мне не изменяет память там можно посылать запрос всего на 1 http url и только потом на другой, по очереди. Grequests же как написано можно послать одновременно хоть на 10 URL тоесть асинхронность. Но как это сделать я не знаю, я уже пробовал . В файле примерно 150 url. Код:
import grequests simplesite = 'http://shost-craft.su' with open("C:\\cruelnetwork\\cruel.need\\wolfs.txt") as werewolves: array = [row.strip()+simplesite for row in werewolves]
params = {'a':'b', 'c':'d'} rs = (grequests.post(u, data=params) for u in array) grequests.map(rs) print(rs)
Ждал где-то минуту Я так понял, это очень долго. И вот не знаю как решить данную проблему. Или все же это как раз таки быстро? В конце было выведено на экран: at 0x0000029AD8D29A98> Я хочу чтобы сразу же отослался запрос на 10 URL-адресов, не по очереди, а сразу же на 10 адресов. Или же нельзя реализовать с помощью данной библиотеки?


Ответ

Библиотека grequests является асинхронной обёрткой над обычной requests. Соответственно когда вы отдали пачку request объектов в grequests.map(), вы получите list объектов response, примерно такого вида
[, , , , None, ]
И вы уже работаете с ними как с обычными requests.Response.
Например, чтобы увидеть результат работы первого request`a в вашем коде, попробуйте сделать так, например:
import grequests simplesite = 'http://shost-craft.su' with open("C:\\cruelnetwork\\cruel.need\\wolfs.txt") as werewolves: array = [row.strip()+simplesite for row in werewolves]
params = {'a':'b', 'c':'d'} rs = (grequests.post(u, data=params) for u in array) responses_list = grequests.map(rs) print(responses_list[0].text) print(rs)
Если вы уточните, что конкретно вы хотите получить, возможно удастся дать более точные рекомендации
EDIT: под капотом эта библиотека использует gevent с пулом задач (подробнее про неё и асинхронность, например тут), он блокирует вызов до конца выполнения всей пачки, но не блокирует выполнение каждой задачи в пачке. Вы можете управлять размером пула. Я написал "первого request`a" выше потому, что не стал заморачиваться с циклом. Могу предложить такое решение:
import grequests simplesite = 'http://shost-craft.su' with open("C:\\cruelnetwork\\cruel.need\\wolfs.txt") as werewolves: array = [row.strip()+simplesite for row in werewolves]
params = {'a':'b', 'c':'d'} rs = [grequests.post(u, data=params) for u in array] for r in grequests.imap(rs, size=10) print(r.status_code, r.url) print(rs)
size=10 - означает закидывать, например, по десять задач в пачке, как только выполниться одна из них докинуть ещё одну (на случай проблем с производительностью)
imap в цикле позволит вам увидеть результаты, сразу после выполнения каждой из задач
Если же вам нужны прям чистые параллельные потоки то да, только множить треды или форкать или ещё что-то, вариантов масса.
EDIT2: приношу извинения за свою некомпетентность по вопросу respons-статусов. Значит ситуация следующая. Учитывая, что автор grequests не использует Error-классы из requests, а делает так
.... def send(self, **kwargs): """ Prepares request based on parameter passed to constructor and optional ``kwargs```. Then sends request and saves response to :attr:`response`
:returns: ``Response`` """ merged_kwargs = {} merged_kwargs.update(self.kwargs) merged_kwargs.update(kwargs) try: self.response = self.session.request(self.method, self.url, **merged_kwargs) except Exception as e: self.exception = e self.traceback = traceback.format_exc() return self
т.е. ловит Exception и закидывает его в ответ. Мы можем поймать его вот таким способом:
import grequests
def exception_handler(request, exception): print("Request failed", request.url) # Сообщить о невалиднсоти и выести url # print(str(exception)) # если хочется подробностей
simplesite = 'http://shost-craft.su' with open("C:\\cruelnetwork\\cruel.need\\wolfs.txt") as werewolves: array = [row.strip()+simplesite for row in werewolves]
params = {'a':'b', 'c':'d'} rs = [grequests.post(u, data=params) for u in array] for r in grequests.imap(rs, size=10, exception_handler=exception_handler) print(r.status_code, r.url)
Теперь если запрос по какой-то причине не выполнился мы, об этом узнаем. Можно получить только статуc_коды запросов которые завершились без Exception`а. Т.е. 404 и другие ошибки клиента или сети не вернуться в итоговый list. Правда остаётся вопрос как же разобрать статус. Могу сделать предположение, что можно попытаться вытащить из exception информацию, которую можно использовать для сравнения с одним из этих типов ошибок, и далее раскрутить до статусов. Но учитывая, что все найденные исходники просто игнорируют этот вопрос, то тут только на ваше усмотрение.

Действительно ли нужно ли создавать интерфейсы для всех объектов?

При разработке я пользуюсь интерфейсами, только там где мне кажется это необходимым. Но тут читаю книгу о патернах (Эрих Гамма) и там вот так написано
В объектно-ориентированных системах интерфейсы фундаментальны. Об объектах известно только то, что они сообщают о себе через свои интерфейсы. Никакого способа получить информацию об объекте или заставить его что-то сделать в обход интерфейса не существует. Интерфейс объекта ничего не говорит о его реализации;
Означает ли это то, что действительно нужно создавать интерфейсы для каждого объекта в программе?


Ответ

Нет, не означает. В литературе по объектно-ориентированному программированию (ООП) под интерфейсом могут пониматься разные значения:
1) Интерфейс - класс, который содержит только чисто виртуальные методы и не содержит данных (это то значение, что вы употребляете в своём вопросе). Конкретное определение.
2) Интерфейс как более абстрактное понятие. Методы, через которые класс выполняет свои контрактные обязанности. Например, есть класс (не интерфейс) Stack, у которого есть методы push и pop, и пусть он будет реализован через массив. Так вот, "Об объектах известно только то, что они сообщают о себе через свои интерфейсы." - означает, что класс Stack предоставляет методы положить элемент на стек и снять с него. "Никакого способа получить информацию об объекте или заставить его что-то сделать в обход интерфейса не существует" - нельзя получить информацию, что Stack реализован на массиве. Того, кто пользуется этим классом, не должно касаться, как он [класс] внутри устроен. И тем более этот "user" не может пролезть внутрь класса и вставить в середину массива элемент.
Вы правильно делаете, если используете интерфейс (1 опр.), когда это необходимо. В тексте говорится про (2 опр.).

Тайна вырезания контура в фигуре SVG

Есть две версии иконки SVG. На одной стрелка вырезается, а на второй - нет, хотя технологически всё верно. Почему не вырезается во второй и как исправить?
svg {width: 120px;}

Иконка №1:

Иконка №2:



Ответ

По умолчанию правило SVG - fill-rule принимает значение равное nonzero В патче иконки два подпути (начинаются с команды M) - первый рисует облако, второй подпуть стрелку. При правиле fill-rule="nonzero", где будет закрашенная область, а где "дырка" - зависит от взаимного направления подпутей. Подробнее на русском о правиле fill-rule здесь В первой иконке в вопросе автора, два подпути идут навстречу друг другу, поэтому внутренняя область стрелки будет незакрашена см. Рис.2 Сделал для наглядности пример анимации: подпуть рисующий облако движется против часовой стрелки. Подпуть стрелки - по часовой.
Анимация начинается при клике.
Cloud Arrow Click me

Как использовать Анимацию в Android без остановки?

Как использовать Анимацию в Android без остановки?


Вся проблема в том что анимация происходит как то не так. Тобишь она воспроизводится. Под конец останавливается на 500мс. А после опять воспроизвордиться. А можно ли как то зациклить это чтобы она вообще не останаваливалась. Тобишь было ЕДИНЫМ Целым


Ответ

Описанное, вроде, похоже на действие дефолтного интерполятора, который определяет как анимация должна проигрываться с течением времени. По дефолту она проигрывается с ускорением в начале и замедлением в конце. Чтобы скорость не менялась надо использовать линейный интерполятор:
android:interpolator="@android:anim/linear_interpolator"
Полезная инфа: http://developer.alexanderklimov.ru/android/animation/interpolator.php

Оператор присваивания и swap

Есть такая реализация оператора присваивания
Matrix & Matrix::operator =(const Matrix& m2) { if (this != &m2) { (Matrix(m2)).swap(*this); } return *this; }
И функции swap:
void Matrix::swap(Matrix & x) { std::swap(x.matrix, matrix); std::swap(x.columns, columns); std::swap(x.rows, rows); }
Вопрос, почему оператор присваивания принимает объект по ссылке, как и функция swap, т.е. как я понимаю в процессе работы например такого кода:
Matrix A,B; A=B;
В качестве параметра для оператора присваивания будет передан B, а в функцию swap А, как итог произойдет обмен значениями, но разве объект B при этом не испортится, ведь его передают по ссылке


Ответ

В передаче по ссылке ничего плохого нет. Совсем не обязательно, что объект испортится, если его передать по ссылке в какую-то функцию. Более того, если его передать по const ссылке, то он гарантированно не изменится. Зато при передаче объекта по ссылке мы экономим на его копировании. (Не вызываем конструктор копирования, как при передачи по значению).
В качестве параметра для оператора присваивания будет передан B, а в функцию swap А
Всё верно. В оператор присваивания действительно будет передан B по ссылке. И даже будет передан по константной ссылке, что гарантирует неизменяемость этого объекта внутри функции. А в функцию swap будет передан действительно объект A по ссылке, но вот функция swap будет вызвана не у объекта B, а у его копии. Так как вызовем мы её у объекта Matrix(m2). То есть мы создадим новый объект Matrix с помощью конструктора копирования. И обмениваться значениями будет объект A с этой копией, что, разумеется, никак не повлияет на исходный объект B.

PHP:Как вывести дерево категорий?

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

//Выбираем данные из БД $result=mysql_query("SELECT * FROM categories"); //Если в базе данных есть записи, формируем массив if (mysql_num_rows($result) > 0){ $cats = array(); //В цикле формируем массив разделов, ключом будет id родительской категории, а также массив разделов, ключом будет id категории while($cat = mysql_fetch_assoc($result)){ $cats_ID[$cat['id']][] = $cat; $cats[$cat['parent_id']][$cat['id']] = $cat; } }
function build_tree($cats,$parent_id,$only_parent = false){ if(is_array($cats) and isset($cats[$parent_id])){ $tree = '

    '; if($only_parent==false){ foreach($cats[$parent_id] as $cat){ $tree .= '
  • '.$cat['name'].' #'.$cat['id']; $tree .= build_tree($cats,$cat['id']); $tree .= '
  • '; } }elseif(is_numeric($only_parent)){ $cat = $cats[$parent_id][$only_parent]; $tree .= '
  • '.$cat['name'].' #'.$cat['id']; $tree .= build_tree($cats,$cat['id']); $tree .= '
  • '; } $tree .= '
'; } else return null; return $tree; }
echo build_tree($cats,0);//результат в html
результат в виде html:

Вопрос: возможно ли получит дерево категории в виде массива не зависимо от вложенности


Ответ

Вопрос: возможно ли получит дерево категории в виде массива не зависимо от вложенности ?
Отвечаю на этот вопрос во втором примере ! Хотя и первый тоже может понадобится.В моём коде он выводит категории в dropdown lists(

';
print_r(CreateTree($arr));

2. Результат: Многомерный массив с иерархической вложенностью:
function CreateTree($array,$sub=0) { $a = array(); foreach($array as $v) { if($sub == $v['parent_id']) { $b = CreateTree($array,$v['id']); if(!empty($b)) $a[$v['name']] = $b; else $a[$v['id']] = $v['name']; } } return $a; } echo "
";
print_r(CreateTree($arr));

    

В каком слое нужно реализовывать логику выбора источника данных (локальные данные или сеть)?

В каких случаях Domain слой (бизнес-логика) может знать о существовании разных источников данных? Например, у меня есть такой код:
GetUserUseCase {
UserRepository userRepository;
GetUserUseCase(UserRepository userRepository) { //... }
public Observble getUser(int id) { return Observable.merge(userRepository.getLocal(id), userRepository.getRemote(id)); }
}
т.е. мой репозиторий может отдавать данные из двух источников. Насколько это корректно с точки зрения "Чистой архитектуры"?
Это простой пример, у меня есть более сложные кейсы, когда мне необходимо точно знать из какого источника получены эти данные. Должен ли я пересмотреть свою архитектуру таким образом, чтобы UseCase не знал о разных источниках, т.е. у меня в репозитории был бы один метод getUser(), или это нормальная ситуация?


Ответ

Зависит от требований к приложению, глобально есть два подхода:
1) Умный репозиторий Тогда это на уровне репозитория, а интерактор только просит данные. То есть бизнес логика без понятия откуда и как получены данные. А репозиторий управляет всеми кешами.
2) Глупый репозиторий Репозиторий только знает как достать и как сохранить данные, а интерактор сам говорит откуда и когда. А также именно интерактор решает когда сохранять, очищать данные и так далее
Обычно на практике более прост первый подход, так как пользователю и логике приложения не известно про локальные кеши и прочее.

Ошибка после смены версии PHP

После смены версии PHP с 5.4 на 7.0 появилась ошибка:
Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; Browser has a deprecated constructor in /home/u408663914/public_html/core/class/browser.php on line 135
Помогите, пожалуйста, исправить!
Строка 135: class Browser {
Весь код файла: http://ideone.com/CcefNk


Ответ

У вас в классе есть метод с таким же названием как и класс:
public function Browser($useragent="") { $this->reset(); if( $useragent != "" ) { $this->setUserAgent($useragent); } else { $this->determine(); } }
Уже давно так не рекомендуют делать, вместо этого используйте магический метод __construct
public function __construct($useragent="") { $this->reset(); if( $useragent != "" ) { $this->setUserAgent($useragent); } else { $this->determine(); } }
UPD. Как верно подметил @xEdelweiss если используете сторонюю библиотеку, то лучше обновите её, вместо того чтобы самому менять исходный код.

Обращение к методу, который не реализован в интерфейсе

Есть интерфейс:
public interface Animal { void eat(); void sleep(); void go(); }
Есть 2 класса животных (представлен 1):
public class Tiger implements Animal { private int x; //координаты нахождения private int y;
public Tiger(int x, int y { this.x = x; this.y = y; }
@Override public void eat() {}
@Override public void sleep() {}
@Override public void go() {}
public int getX() { return x; }
public int getY() { return y; } }
И класс Locator
public class Locator { private int x; private int y;
public Locator(int x, int y) { this.x = x; this.y = y; }
public void find(Animal animal) { /** * Метод сравнивает координаты локатора и координаты животного. * Если координаты совпадают, выводится сообщение */ } }
Нужно в методе find класса Locator обратиться к animal.getX(). Как это сделать, не изменяя интерфейс и не используя явное приведение типов ((Tiger)animal). И вообще, возможно ли это?


Ответ

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

Как объединить два exe файла в один

Имеется программа в виде одного исполняемого файла, доступа к ее исходникам нет. Также есть вспомогательная программа, которая, исходя из особенностей операционной системы, запускает основную программу с определенными параметрами(к ее исходникам доступ есть). Сейчас вспомогательная программа принимает путь до основной и запускает ее. Как объединить обе программы в один exe файл?


Ответ

Проще всего добавить этот exe в ресурсы Вашей программы и загружать его через FindResource/LoadResource/LockResource
Похожий вопрос с аналогичным решением: how to use a resource file (txt - tab delimited) as a data source for win32 application (тут в ответах масса вариаций на одну и ту же тему)

Кроме того, этот вариант позволяет модифицировать такой ресурс без пересборки Вашего приложения (например, когда появляется новая версия).
Пример из msdn: Updating Resources

Почему ifstream не воспринимает абсолютный путь к файлу в linux?

Так работает:
ifstream list("../../../.Alarm_clock/output.txt");
Так - нет:
ifstream list("$HOME/.Alarm_clock/output.txt");


Ответ

Насколько я могу судить о Linux (я в нем не слишком знаток), $HOME - указание для оболочки подставить значение переменной среды HOME. Что конструктор ifstream, естественно, не делает.
Воспользуйтесь соответствующей функцией - как я понимаю, getenv("HOME"), и соберите полный путь к файлу.

Как отключить эффект перехода между Activity?

Добрый день, хочу написать приложение справочник в котором будут переходы между Activity. Но мне не нравиться сам эффект перехода, он похож на браузерный, когда мы переходим по ссылки, сначала открывается белое окно, а после появляется контент.
Возможно сделать что-то вроде полноценного приложения? Или нужно весь контент размещать в одном Activity?


Ответ

Есть специальный метод, позволяющий переопределить анимации
startActivity(new Intent(....)); overridePendingTransitions(0, 0);
0, 0 это параметры exitAnimation и enterAnimation. Можете сами создать анимацию, и передать ее Id в данный метод. 0 значит, что анимации в данном случае не будет.

Отловить изменение содержимого div

У меня есть div, содержимое которого может меняться различными способами: например, весь его контент может быть изменён через innerHTML, или могут быть добавлены узлы через DOM-методы. Это может произойти через собственный javascript или через вызовы jQuery API, или через другие библиотеки.
Я хочу выполнить некоторый код, когда содержимое div изменится, но я абсолютно не контролирую, когда он изменится. Действительно, я разрабатываю плагин, который может использоваться другими людьми, которые могут свободно изменять содержимое своих div'ов так, как они предпочитают. Когда внутреннее содержимое этого div изменяется, форма плагина также может быть обновлена.
Я использую jQuery. Есть ли способ отловить изменение содержимого div?


Ответ

MutationObserver (поддержка)
const observer = new MutationObserver(mutations => console.log(mutations)); observer.observe(test, { attributes: true, childList: true, characterData: true, subtree: true }); test.innerHTML = '1'; test.classList.add('test'); test.appendChild(document.createElement('br')); test.innerHTML += '2';


Пропорциональное вписывание изображения

Нужно вписать изображение в div фиксированного размера, но так, чтобы больший размер изображения занимал 100% div'а, а меньший - сколько получится. Если подгонять только один фиксированный размер, то это выглядит так
div { width: 125px; height: 70px; } div img { width: 100%; height: auto; }
Но если у изображения высота больше, чем ширина, то получается швах. Решается ли проблема на CSS?


Ответ

Если я правильно понял вопрос, то вам нужно свойство background-size. Например:
div { background: url(/example/image/mybg.png) 100% 100% no-repeat; background-size: contain; }
cover
Масштабирует изображение с сохранением пропорций так, чтобы его ширина или высота равнялась ширине или высоте блока.
contain
Масштабирует изображение с сохранением пропорций таким образом, чтобы картинка целиком поместилась внутрь блока.
Источник: https://webref.ru/css/background-size

А если именно с тегом img нужно, то может такое решение устроит?
.ex1 { width: 70px; height: 125px; } .ex2 { width: 125px; height: 70px; } div { border: 1px solid #ccc; display: inline-block; margin: 10px; position: relative; } div img { position: absolute; height: auto; width: auto; max-height: 100%; max-width: 100%; }


Правильно ли я понимаю концепцию инъекции зависимостей?

Моё понимание сути depency injection. Тезисно.
Все классы вызываются через метод класса DI. Атрибут класса DI содержит список зависимостей классов. Внутри DI, классы чьи зависимости описаны, вызываются так же - через DI, реализуя их все.
DI работает по принципу ленивой загрузки. То есть, создает объекты только при необходимости, все остальное время только хранит соответствия интерфейсов реализациям и свои внутренние настройки.
Пример работы DI
Составляю список (массив) соответствия классов и их зависимостей. При попытке создания объекта через DI (условно $DI->create('
amespace\ClassName') вместо new
amespace\ClassName), проверяю наличие зависимостей в массиве для вызываемого класса и если необходимо, подменяю определенные аргументы, необходимыми классами в соответствии с правилами из массива. После этого возвращаю созданный объект.
Правильно ли я понял алгоритм работы depency injection?
Если есть конструктивные замечания, поправьте (желательно с ссылками).
p.s. понимание принципа работы составил после прочтения этого


Ответ

DI не обязательно работает по принципу ленивой загрузки. Ленивая загрузка - это оптимизация уже сверх того, что призвано делать внедрение зависимостей
Внедрение зависимостей - это прежде всего абстрактная идея, которая не имеет какой-то единственно правильной реализации в коде. Суть идеи в отказе от управлении зависимостями самими объектами. То есть, обычно, в отказе от создания самим объектом экземпляров каких-то классов, которые нужны этому объекту для работы.
Если ваш объект сам создаёт какие-то классы, а не получает их извне готовыми, то это уже не внедрение зависимостей.
Например, у вас есть объект корзины, которому необходимо что-то сохранять в БД.
Если не использовать DI, то объекту корзины самому нужно будет получить откуда-то объект DAO чтобы сохранить что-то в БД. Тут вы сразу сталкиваетесь с необходимостью использовать какой-то синглтон, и с очевидными проблемами при тестировании объекта корзины в отвязке от какой-то БД. Объекту корзины придётся знать что за такие объекты DAO, с которыми он работает. В случае использования DI объект корзины по умолчанию не пытается создать объект, а ожидает (и предоставляет методы) что ему укажут извне, при или сразу после инициализации, куда и к какому объекту нужно обращаться для добавления записей в БД.
Такой подход даёт много преимуществ как упрощая сами классы, так и упрощая тестирования и изменение. Если вам когда-нибудь захочется использовать совсем другой объект DAO, то для этого вам не нужно будет менять объект корзины, при условии, конечно, что тот ждёт на вход интерфейс, а не конкретный объект.
Конечно, всё имеет свою цену. Программы, использующие DI, становятся более сложными для понимания, так как та логика, которая раньше была в одном месте, оказывается раскидана по всей программе. Стоит ли платить эту цену, и так ли вам нужны все достоинства этого подхода - решать нужно взвешенно по фактической ситуации. Для каких-то простых программ можно обойтись без DI вообще. На стадии прототипа тоже может и не нужно никакое DI. Если же вы хотите сделать максимально усложнить понимание вашей программы, то использование DI обязательно во всех ситуациях
Родственным для DI паттерном является паттерн MVC. Идея MVC несколько более конкретная, потому что в MVC подразумеваются конкретные роли у составных частей. Базу данных вы прячете за контроллером, а корзина ничего не знает о БД, но знает к какому контроллеру её следует обращаться в случае каких-то событий. То есть, вы тоже приходите к тому что внедряете в объект корзины её зависимость в виде контроллера.
Практический пример
У вас есть интерфейс для получения и сохранения каких-то данных.
interface DAO { public function save($data); public function load(); }
У вас есть объект корзины, который ждёт что при инициализации ему сообщат куда нужно обращаться за данными, и куда сохранять.
class Cart { private $dao; private $items = [];
public function __construct(DAO $dao) { $this->dao = $dao; $this->items = $this->dao->load(); }
public function add($item, $qty = 1) { $this->items[$item] += $qty; $this->dao->save($this->items) }
public function delete($item) { $this->items[$item] = 0; $this->dao->save($this->items) }
/* Другие обычные методы пропустим */ }
У вас есть конкретная реализация интерфейса.
class SessionDAO implements DAO { /* Методы инициализации придумайте сами */
public function save($data) { // куда-то сохраняете } public function load() { // откуда-то загружаете } }
Теперь вы можете сами в правильной последовательности создать объект DAO, передав его объекту корзины при инициализации.
$dao = new SessionDAO(); $dao->initWithKey(/* ... */);
$cart = new Cart($dao); $cart->add('Example', 10);
Как видите, в корзине нигде не инициализируются объекты, которые нужны корзине для работы. Все необходимые объекты корзина получает из внешнего мира.
Нет никакой причины, которая помешала бы вам сделать ленивое DAO, которое инициализировалось только в момент использования:
class LazySessionDAO implements DAO { private $dao;
private function getConcreteDAO() { // отложенно инициализируем DAO при необходимости if (!$this->dao) { $this->dao = new SessionDAO(); $this->dao->initWithKey(/* ... */); }
return $this->dao; }
public function save($data) { $this->getConcreteDAO()->save($data); }
public function load() { $this->getConcreteDAO()->load(); } }
Как видите, для этого ровным счётом ничего не нужно было менять в объекте корзины. Именно потому внедрение зависимостей так любят и ценят.
Теперь к упомянутому в статье Phemto. Это - dependency injection container или dependency injector, а не просто dependency injection. Один из многих.

Вызов нескольких функций класса разом

Сразу извиняюсь если некорректно назвал топик, но интересует такая тема:
class my_class{ } $test = new my_class(); $test->func1()->func2()->....->funcN();
Интересует момент, можно (и если можно, то как) реализовать такой момент:
$test->func1()->func2()->....->funcN();


Ответ

Нашел решение, называется Fluent Interface
class my_class{ public function funcA() { return $this; } public function funcB() { return 'Вызов N2'; }
}
$t = new my_class(); echo $t->funcA()->funcB();

Зависимости в docker и место на диске

Правильно ли я понимаю, что каждый образ вот так вот тащит в зависимостях свою собственную ОС (дебианы всех версий, убунты всех версий, alpin'ы всех версий, что там ещё есть), из-за чего куча разных образов очень быстро сожрут свободное место на диске?


Ответ

Да, вы получите образы всех (почти-)ОС Из зависимостей всех ваших образов. Нет, это не съест весь ваш диск в один момент.

Во-первых, Docker старается избегать дублирования данных с помощью драйверов хранения (storage drivers)
Большинство образов Docker основано на каких-то других образах (директива FROM в Dockerfile). И как правило, файлы, которые из одного образа унаследовались другими без изменений, будут размещены на диске всего раз. Как именно и как будет организована работа с такими файлами — зависит от драйвера. На странице о драйверах можно почитать о технических подробностях каждого из них, для примера:
Aufs представляет файловую систему контейнера в виде объединения слоёв, начиная с базового (только для чтения), через промежуточные (только для чтения) и заканчивая собственным слоем контейнера (доступным для записи). ZFS размещает базовую файловую систему прямо на устройстве хранения, а каждый очередной слой (включая собственный слой контейнера) накладывается в виде клона (clone) из снимка (snapshot) предыдущего слоя. История файлов хранится лишь по одной версии для слоя. То есть, если при сборке слоя файл был изменён дважды, сохранится лишь последняя версия. Если был создан и удалён, то в слое не будет упоминаний о нём вовсе. Удаление файлов из исходного образа реализуется путём "замазывания" (whiteout) файлов специальными записями.

Во-вторых, в образах ОС для Docker, по сравнению с серверными ОС (чтобы сразу исключить из рассмотрения GUI и связанные вещи), многих вещей нет за ненадобностью:
Инит-процесса и его аксессуаров. Docker стартует сразу процесс с "полезной нагрузкой", бывает что через оболочку, занимающую PID 1. Собственное ядро и утилиты для его обслуживания. Всё равно используется ядро хост-машины. Поэтому контейнеры так привязаны к ОС, на которой построены. Демонов. Хорошей практикой считается держать в каждом контейнере ровно один процесс, поэтому файлы, связанные с демонами (почтовый агент, базы данных, системы автоообновления, и т. п.), можно выбросить. Кому надо будет — поставит самостоятельно, но это редко нужно. Устаревающих файлов, вроде списков пакетов из репозиториев. Их всё равно надо будет заменить свежими версиями при наследовании образа, поэтому включать их в образ бесполезно. Популярная проблема при формировании контейнеров: пакеты не устанавливаются, если в докерфайле явно не потребовать обновить списки пакетов из репозиториев.
Достаточно часто в контейнерах используется Alpine Linux, контейнерная версия которого занимает чуть больше 4 мегабайт (но при наследовании она чуть прибавляет в весе за счёт временных файлов). Для сравнения, его же самостоятельный установочный образ для полноценных систем занимает чуть больше 100 мегабайт.
Другие контейнерные дистрибутивы потолще будут, но и они по сравнению со своими полновесными собратьями гораздо компактнее.

Проблемы с BASS

Пытаюсь скомпилировать такой код:
/* BASS simple console player Copyright (c) 1999-2015 Un4seen Developments Ltd. */
#include #include #define BASSDEF(f) (WINAPI *f) // define the functions as pointers #include "bass.h"
#ifdef _WIN32 // Windows #include #else // OSX/Linux #include #include #include #include
#define Sleep(x) usleep(x*1000)
int _kbhit() { int r; fd_set rfds; struct timeval tv={0}; struct termios term,oterm; tcgetattr(0,&oterm); memcpy(&term,&oterm,sizeof(term)); cfmakeraw(&term); tcsetattr(0,TCSANOW,&term); FD_ZERO(&rfds); FD_SET(0,&rfds); r=select(1,&rfds,NULL,NULL,&tv); tcsetattr(0,TCSANOW,&oterm); return r; } #endif
// display error messages void Error(const char *text) { printf("Error(%d): %s
",BASS_ErrorGetCode(),text); BASS_Free(); exit(0); }
void ListDevices() { BASS_DEVICEINFO di; int a; for (a=1;BASS_GetDeviceInfo(a,&di);a++) { if (di.flags&BASS_DEVICE_ENABLED) // enabled output device printf("dev %d: %s
",a,di.name); } }
void main(int argc, char **argv) { DWORD chan,act,time,level; BOOL ismod; QWORD pos; int a,device=-1;
printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player
" "---------------------------------------------------------
");
// check the correct BASS was loaded if (HIWORD(BASS_GetVersion())!=BASSVERSION) { printf("An incorrect version of BASS was loaded"); return; }
for (a=1;a
" "\t-l = list devices
" "\t-d = device number
"); return; }
// initialize output device if (!BASS_Init(device,44100,0,0,NULL)) Error("Can't initialize device");
// try streaming the file/url if ((chan=BASS_StreamCreateFile(FALSE,argv[argc-1],0,0,BASS_SAMPLE_LOOP)) || (chan=BASS_StreamCreateURL(argv[argc-1],0,BASS_SAMPLE_LOOP,0,0))) { pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE); if (BASS_StreamGetFilePosition(chan,BASS_FILEPOS_DOWNLOAD)!=-1) { // streaming from the internet if (pos!=-1) #ifdef _WIN32 printf("streaming internet file [%I64d bytes]",pos); #else printf("streaming internet file [%lld bytes]",pos); #endif else printf("streaming internet file"); } else #ifdef _WIN32 printf("streaming file [%I64d bytes]",pos); #else printf("streaming file [%lld bytes]",pos); #endif ismod=FALSE; } else { // try loading the MOD (with looping, sensitive ramping, and calculate the duration) if (!(chan=BASS_MusicLoad(FALSE,argv[argc-1],0,0,BASS_SAMPLE_LOOP|BASS_MUSIC_RAMPS|BASS_MUSIC_PRESCAN,1))) // not a MOD either Error("Can't play the file"); { // count channels float dummy; for (a=0;BASS_ChannelGetAttribute(chan,BASS_ATTRIB_MUSIC_VOL_CHAN+a,&dummy);a++); } printf("playing MOD music \"%s\" [%u chans, %u orders]", BASS_ChannelGetTags(chan,BASS_TAG_MUSIC_NAME),a,(DWORD)BASS_ChannelGetLength(chan,BASS_POS_MUSIC_ORDER)); pos=BASS_ChannelGetLength(chan,BASS_POS_BYTE); ismod=TRUE; }
// display the time length if (pos!=-1) { time=(DWORD)BASS_ChannelBytes2Seconds(chan,pos); printf(" %u:%02u
",time/60,time%60); } else // no time length available printf("
");
BASS_ChannelPlay(chan,FALSE);
while (!_kbhit() && (act=BASS_ChannelIsActive(chan))) { // display some stuff and wait a bit level=BASS_ChannelGetLevel(chan); pos=BASS_ChannelGetPosition(chan,BASS_POS_BYTE); time=BASS_ChannelBytes2Seconds(chan,pos); #ifdef _WIN32 printf("pos %09I64u",pos); #else printf("pos %09llu",pos); #endif if (ismod) { pos=BASS_ChannelGetPosition(chan,BASS_POS_MUSIC_ORDER); printf(" (%03u:%03u)",LOWORD(pos),HIWORD(pos)); } printf(" - %u:%02u - L ",time/60,time%60); if (act==BASS_ACTIVE_STALLED) { // playback has stalled printf("-- buffering : %05u --",(DWORD)BASS_StreamGetFilePosition(chan,BASS_FILEPOS_BUFFER)); } else { for (a=27204;a>200;a=a*2/3) putchar(LOWORD(level)>=a?'*':'-'); putchar(' '); for (a=210;a<32768;a=a*3/2) putchar(HIWORD(level)>=a?'*':'-'); } printf(" R - cpu %.2f%%
",BASS_GetCPU()); fflush(stdout); Sleep(50); } printf("
");
// wind the frequency down... BASS_ChannelSlideAttribute(chan,BASS_ATTRIB_FREQ,1000,500); Sleep(300); // ...and fade-out to avoid a "click" BASS_ChannelSlideAttribute(chan,BASS_ATTRIB_VOL,-1,200); // wait for slide to finish while (BASS_ChannelIsSliding(chan,0)) Sleep(1);
BASS_Free(); }
Этот пример доступен из коробки. От себя добавил только
#define BASSDEF(f) (WINAPI* f) // define the functions as pointers
иначе не собиралось. После запуска программа, не открывая окно, сразу падает. gdb пишет
Program received signal SIGSEGV, Segmentation fault. 0x00000000 in ?? ()
(gdb) bt #0 0x00000000 in ?? () #1 0x004015c1 in main (argc=1, argv=0xdc15b0) at qks.c:68
Даже этот пример не работает:
#define BASSDEF(f) (WINAPI *f) #include "bass.h"
int main() { BASS_Init(-1, 44100, 0, 0, NULL); }
Компилирую так:
gcc.exe -m32 -Wall -Wextra -Wpedantic -lbass -mwindows qks.c -o qks.exe
ОС - Windows 10 x64; GCC - 4.9.2
UPD
Появился небольшой прогресс. Эта программа компилируется и успешно завершается:
#include #include #include #define BASSDEF(f) (WINAPI *f) #include "bass.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { (void) hPrevInstance, (void) lpCmdLine, (void) nCmdShow;
HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init BASS_Init(-1,44100,0,NULL,NULL) // call BASS_Init }
Вот что написано в документации:
The downside is that you have to manually import each function that you use, with the GetProcAddress function. But it has been made a lot simpler to import BASS this way by the use of the BASSDEF #define. Here's a small example:
#define BASSDEF(f) (WINAPI *f) // define the functions as pointers #include "bass.h" ... HINSTANCE bass=LoadLibrary("BASS.DLL"); // load BASS BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init BASS_Init(-1,44100,0,hWnd,NULL); // call BASS_Init
Однако при попытке получить адрес других функций ловлю предупреждение:
warning: assignment from incompatible pointer type BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion");
И если вызвать эту функцию (или какие-нибудь другие), то снова происходит SIGSEGV
UPD 2
Приведенный выше пример работает, если добавит в начало тела main эти строки:
HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion"); BASS_Free=GetProcAddress(bass,"BASS_Free"); BASS_SetVolume=GetProcAddress(bass,"BASS_SetVolume"); BASS_SetConfig=GetProcAddress(bass,"BASS_SetConfig"); BASS_SampleFree=GetProcAddress(bass,"BASS_SampleFree"); BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad"); BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel"); BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay"); BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop"); BASS_GetVolume=GetProcAddress(bass,"BASS_GetVolume"); BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion"); BASS_GetCPU=GetProcAddress(bass,"BASS_GetCPU"); BASS_Pause=GetProcAddress(bass,"BASS_Pause"); BASS_Start=GetProcAddress(bass,"BASS_Start"); BASS_MusicFree=GetProcAddress(bass,"BASS_MusicFree"); BASS_MusicLoad=GetProcAddress(bass,"BASS_MusicLoad"); BASS_ChannelSetAttribute=GetProcAddress(bass,"BASS_ChannelSetAttribute"); BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile"); BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode"); BASS_StreamCreateURL=GetProcAddress(bass, "BASS_StreamCreateURL"); BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength"); BASS_StreamGetFilePosition=GetProcAddress(bass, "BASS_StreamGetFilePosition"); BASS_ChannelGetAttribute=GetProcAddress(bass, "BASS_ChannelGetAttribute"); BASS_ChannelGetTags=GetProcAddress(bass, "BASS_ChannelGetTags"); BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength"); BASS_ChannelBytes2Seconds=GetProcAddress(bass, "BASS_ChannelBytes2Seconds"); BASS_ChannelIsActive=GetProcAddress(bass, "BASS_ChannelIsActive"); BASS_ChannelGetLevel=GetProcAddress(bass, "BASS_ChannelGetLevel"); BASS_ChannelGetPosition=GetProcAddress(bass, "BASS_ChannelGetPosition"); BASS_ChannelSlideAttribute=GetProcAddress(bass, "BASS_ChannelSlideAttribute");
Одно большое "НО": Звук воспроизводиться при запуске из командной строки (cmd.exe, ConEmu), но нет текстовой информации. Т.е. я запускаю программу и она работает в фоне, в терминале сразу появляется приглашение ввода:
user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound > qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3"
user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound >
Однако вся текстовая информация (звук тоже работает) появляется во встроенной консоли SublimeText 3
C:\Users\user\Documents\Projects\sound>qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3" Simple console mode BASS example : MOD/MPx/OGG/WAV player --------------------------------------------------------- streaming file [41587200 bytes] 3:55 pos 000000136 - 0:00 - L ------------- ------------- R - cpu 0.00% pos 000005944 - 0:00 - L ------------- ------------- R - cpu 0.00% pos 000014808 - 0:00 - L ------------- ------------- R - cpu 0.00% pos 000023728 - 0:00 - L ------------- ------------- R - cpu 0.00% pos 000032628 - 0:00 - L ------------- ------------- R - cpu 0.07% pos 000041584 - 0:00 - L ---********** **********--- R - cpu 0.07% pos 000050496 - 0:00 - L -----******** ********----- R - cpu 0.14% pos 000059536 - 0:00 - L -----******** *********---- R - cpu 0.14% pos 000068572 - 0:00 - L -----******** *********---- R - cpu 0.19% pos 000077544 - 0:00 - L -----******** ********----- R - cpu 0.19% pos 000086464 - 0:00 - L -----******** *********---- R - cpu 0.25% pos 000095364 - 0:00 - L -----******** ********----- R - cpu 0.25% ...
Информация о компиляторе (gcc -v):
Using built-in specs. COLLECT_GCC=gcc.exe COLLECT_LTO_WRAPPER=c:/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.8.1/lto-wrapper.exe Target: x86_64-w64-mingw32 Configured with: ../../../src/gcc-4.8.1/configure --build=x86_64-w64-mingw32 --enable-targets=all --enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-libgomp --enable-lto --enable-graphite --enable-cxx-flags=-DWINPTHREAD_STATIC --enable-libstdcxx-debug --enable-threads=posix --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libstdcxx-threads --enable-libstdcxx-time --with-gnu-ld --disable-werror --disable-nls --disable-win32-registry --prefix=/mingw64tdm --with-local-prefix=/mingw64tdm --with-pkgversion=tdm64-2 --with-bugurl=http://tdm-gcc.tdragon.net/bugs Thread model: posix gcc version 4.8.1 (tdm64-2)
Отладка:
user@LAPTOP-OIQUIP0K C:\Users\user\Documents\Projects\sound > gdb.exe qks.exe GNU gdb (GDB) 7.7.50.20140303-cvs Copyright (C) 2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i686-pc-mingw32". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources online at: . For help, type "help". Type "apropos word" to search for commands related to "word".
This binary was built by Equation Solution ... Reading symbols from qks.exe...done. (gdb) b main Breakpoint 1 at 0x4015c5: file qks.c, line 59. (gdb) r -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3" Starting program: C:\Users\user\Documents\Projects\sound\qks.exe -d -1 "C:\Users\user\Music\Radiohead\Creep.mp3" [New Thread 2708.0x16f4] [New Thread 2708.0x4c0]
Breakpoint 1, main (argc=4, argv=0xab2390) at qks.c:59 59 HINSTANCE bass=LoadLibrary("bass.dll"); // load BASS (gdb) n [New Thread 2708.0xd28] 60 BASS_Init=GetProcAddress(bass,"BASS_Init"); // get BASS_Init (gdb) 61 BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion"); (gdb) 62 BASS_Free=GetProcAddress(bass,"BASS_Free"); (gdb) 63 BASS_SetVolume=GetProcAddress(bass,"BASS_SetVolume"); (gdb) 64 BASS_SetConfig=GetProcAddress(bass,"BASS_SetConfig"); (gdb) 65 BASS_SampleFree=GetProcAddress(bass,"BASS_SampleFree"); (gdb) 66 BASS_SampleLoad=GetProcAddress(bass,"BASS_SampleLoad"); (gdb) 67 BASS_SampleGetChannel=GetProcAddress(bass,"BASS_SampleGetChannel"); (gdb) 68 BASS_ChannelPlay=GetProcAddress(bass,"BASS_ChannelPlay"); (gdb) 69 BASS_ChannelStop=GetProcAddress(bass,"BASS_ChannelStop"); (gdb) 70 BASS_GetVolume=GetProcAddress(bass,"BASS_GetVolume"); (gdb) 71 BASS_GetVersion=GetProcAddress(bass,"BASS_GetVersion"); (gdb) 72 BASS_GetCPU=GetProcAddress(bass,"BASS_GetCPU"); (gdb) 73 BASS_Pause=GetProcAddress(bass,"BASS_Pause"); (gdb) 74 BASS_Start=GetProcAddress(bass,"BASS_Start"); (gdb) 75 BASS_MusicFree=GetProcAddress(bass,"BASS_MusicFree"); (gdb) 76 BASS_MusicLoad=GetProcAddress(bass,"BASS_MusicLoad"); (gdb) 77 BASS_ChannelSetAttribute=GetProcAddress(bass,"BASS_ChannelSetAttribute"); (gdb) 78 BASS_StreamCreateFile=GetProcAddress(bass,"BASS_StreamCreateFile"); (gdb) 79 BASS_ErrorGetCode=GetProcAddress(bass,"BASS_ErrorGetCode"); (gdb) 80 BASS_StreamCreateURL=GetProcAddress(bass, "BASS_StreamCreateURL"); (gdb) 81 BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength"); (gdb) 82 BASS_StreamGetFilePosition=GetProcAddress(bass, "BASS_StreamGetFilePosition"); (gdb) 83 BASS_ChannelGetAttribute=GetProcAddress(bass, "BASS_ChannelGetAttribute"); (gdb) 84 BASS_ChannelGetTags=GetProcAddress(bass, "BASS_ChannelGetTags"); (gdb) 85 BASS_ChannelGetLength=GetProcAddress(bass, "BASS_ChannelGetLength"); (gdb) 86 BASS_ChannelBytes2Seconds=GetProcAddress(bass, "BASS_ChannelBytes2Seconds"); (gdb) 87 BASS_ChannelIsActive=GetProcAddress(bass, "BASS_ChannelIsActive"); (gdb) 88 BASS_ChannelGetLevel=GetProcAddress(bass, "BASS_ChannelGetLevel"); (gdb) 89 BASS_ChannelGetPosition=GetProcAddress(bass, "BASS_ChannelGetPosition"); (gdb) 90 BASS_ChannelSlideAttribute=GetProcAddress(bass, "BASS_ChannelSlideAttribute"); (gdb) 95 int a,device=-1; (gdb) 97 printf("Simple console mode BASS example : MOD/MPx/OGG/WAV player
" (gdb) 101 if (HIWORD(BASS_GetVersion())!=BASSVERSION) { (gdb) 0x744d59c6 in ?? () (gdb) ni 0x744b10f9 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45c5 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45c6 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45cc in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45d2 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45d4 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45d6 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45ee in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45f0 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b45f1 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b10fe in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b1101 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b1103 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744b1104 in ?? () from C:\Users\user\Documents\Projects\sound\bass.dll (gdb) 0x744d59cb in ?? () (gdb) 0x744d59d0 in ?? () (gdb) 0x00401976 in main (argc=4, argv=0xab2390) at qks.c:101 101 if (HIWORD(BASS_GetVersion())!=BASSVERSION) { (gdb) n 106 for (a=1;aСистема:
OS: Windows 10 x64 CPU: AMD A9-9410 RADEON R5, COMPUTE CORES 2C+3G 2.90 GHz
Команды компиляции и запуска:
gcc.exe -g -std=c11 -m32 -Wall -Wextra -Wpedantic -lbass -mwindows qks.c -o qks.exe qks.exe -d -1 "C:\Users\user\Music\Eminem\Rap God.mp3"


Ответ

Есть такая штука - ABI - то есть описание того, как функция/класс будет представлена в бинарном виде. Это очень важно, когда линкуются два разных куска кода (например, exe и статическая библиотка) или просто вызываются (например, обращение к dll). В некоторых случаях линковщик (а это его работа) может проверить, что интерфейс не совпадает и поднять панику. А может и не знать или проигнорировать.
Если два куска кода не совместимы на уровне ABI, то может произойти все что угодно. Самый простой пример - вызывающая сторона ожидает параметры в регистрах, а вызываемая - в стеке. Что именно прочитается со стека - никто не знает. В лучшем случае упадет с Access violation.
В случае чистого Си эту проблему достаточно хорошо решили (всякие stdcall, cdecl и подобное). А вот в случае с++ все сильно сложнее - есть классы, а им нужно хранить данные, которые никак не стандартизированы. Даже если использовать только gcc, он может использовать различное ABI. Из последнего, на что я лично натолкнулся, это сильно измененный ABI при переходе от 4.9.х на 5.4.х (он вроде после 5.2 поменялся). Здесь есть много деталей.
Теперь ближе к проблеме. По внешнему виду файла обычно сложно догадаться, какой версией компилятора он собран. Но её можно попробовать угадать. Судя по всему, там внутри все собрано с помощью vc6 (это очень древнее существо) и более-менее свежие gcc с ним поэтому и не совместимы. А старые - да. @VadimTagil просто повезло, что он угадал правильную версию.
Что делать? использовать gcc 3.4 как не очень, как по мне, поэтому, лучше взять сорцы и пересобрать их именно тем gcc, которым будет собираться все остальное. Благое дело, там есть makefile и студийный проект.

С99 и объявление переменной

Стандартом написано что переменные в блоке создаются при входе в него. Но как в С99, если в нем переменные можно объявлять не в начале блока? Все равно создаются при входе в блок?


Ответ

Понимаете, вопрос о том, когда именно они создаются - совершенно праздный. Допустим, создаются в начале блока. Или, допустим, не создаются в начале блока. Или при одном ключе создаются, при другом - нет.
Вы-то все равно, пока не достигнете объявления переменной, никак не можете к ней обратиться. Очень многое зависит от оптимизатора - решит ли он размещать переменную в стеке или в регистре, разместит ли он ее в отдельной области памяти или в области, которая была занята другой переменной, но которая больше не используется.
Так что дать точный ответ на вопрос, как мене кажется, можно один - depends on :) Не уверен (если ошибаюсь - пусть гуру поправят), но такие вещи стандарт должен отдавать на откуп компилятору.

Как сложить время двух дат?

Есть две даты:
DateTime date1 = new DateTime(0001, 1, 1, 0, 0, 5); DateTime date2 = new DateTime(0001, 1, 1, 0, 0, 5);
Как сложить только время двух дат? Как к одной дате прибавить только часы/минуты/секунды другой даты?


Ответ

Свойство DateTime.TimeOfDay возвращает TimeSpan, соответствующий интервал дня, прошедший с полуночи.
метод Add у DateTime, принимает TimeSpan, поэтому прибавление времени к дате может выглядеть так:
DateTime date = date1.Add(date2.TimeOfDay);

Как сделать border-image в форме волны (wave)?

Ребята как сделать так чтобы border-image был наоборот повернут вниз через CSS пытаюсь уже какой раз, не получается. Должен быть как в картинке в приложении ниже.

.wave{ height: 50px; position: relative; } .wave::before{ content: ""; position: absolute; left: 0; bottom: 0; right: 0; background-repeat: repeat; height: 10px; background-size: 20px 20px; background-image: radial-gradient(circle at 10px -5px, transparent 12px, aquamarine 13px); } .wave::after{ content: ""; position: absolute; left: 0; bottom: 0; right: 0; background-repeat: repeat; height: 15px; background-size: 40px 20px; background-image: radial-gradient(circle at 10px 15px, aquamarine 12px, transparent 13px); }



Ответ

Как то так
.wave{ height: 50px; position: relative; background-color: red; overflow: hidden; } .wave::before{ content: ""; position: absolute; left: 0; top: 0; right: 0; background-repeat: repeat; height: 10px; background-size: 20px 20px; background-image: radial-gradient(4px 5px at bottom, transparent 12px, aquamarine 13px); } .wave::after{ content: ""; position: absolute; left: -10px; top: 0; right: 0; background-repeat: repeat; height: 15px; background-size: 40px 20px; background-image: radial-gradient(circle at top, aquamarine 14px, transparent 12px); }


Не создаётся массив из индексов

Здравствуйте! Объясните, пожалуйста, почему не работает данный код? var arr = new Array(10).map(function (t, iter) { return iter }); console.log(arr);
По логике должен получиться массив [0,1,2,3,4,5,6,7,8,9], но вместо него 10 элементов undefined


Ответ

https://www.w3schools.com/jsref/jsref_map.asp
Note: map() does not execute the function for array elements without values.
то есть
map не вызывается для элементов массива без значений.
Можете добавить console.log внутрь функции параметра map, чтобы в этом убедиться.
А вот отсюда https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map :
Due to the algorithm defined in the specification if the array which map was called upon is sparse, resulting array will also be sparse keeping same indices blank.
то есть
Из-за определения алгоритма данного в спецификации, если исходный массив - разреженный, полученный массив тоже будет разреженным, с пустыми соответствующими элементами.

При выводе text.setText(R.string.slovo + “ ” + intValue); - выводится инт адрес ресурса

При выводе text.setText(R.string.slovo + " " + intValue);- выводится int адрес ресурса.Нужно чтобы выводился String из ресурса плюс intValue. intValue меняется динамически поэтому загонять его в ресурсы смысла нет.


Ответ

Все правильно вы должны образаться к ресурсам черех getResources. Пример
getResources().getString(R.string.slovo )

Почему в разных компиляторах код выводит разные значения? [закрыт]

http://rextester.com/ZZGGK27907 http://rextester.com/IGXLV67756
В данных ссылках один и тот же код. Но отличается для компиляторов C++ и C++11. В C++ ответ выводится верный. А в C++11 выводится просто 0. По идее, C++ и C++11 не должны сильно отличаться.
Почему может выводится разный ответ в одинаковых кодах? И где может быть ошибка?


Ответ

Не сильно вдавался в алгоритмические подробности, но как минимум одно проблемное место нашел:
stack path; for(int index = Q.front().idx; index != -1; ) { ...
Я попробовал прогнать ваш код на указанном наборе входных данных и обнаружил, что к указанному моменту очередь Q оказывается пуста (не углублялся, должно так быть или нет). Соответственно Q.front().idx обращается к первому элементу пустой очереди. В результате возникает неопределенное поведение. А раз оно неопределенное, то, в зависимости от компилятора, программа ведет себя по разному. Как-то вам нужно этот момент корректно обойти или (если он - не то что вы ожидали), починить код до указанного.

JS изменить текст на другой вкладке

Допустим открыта страница в браузере mysite.com/page-1.php в которой есть элемент:

Далее в новой я открываю страницу mysite.com/page-2.php в которой есть js команда которая должна сменить текст в элементе test-1 в первой вкладке - mysite.com/page-1.php
Возможно ли как то выполнить данную задачу средствами js/jquery?


Ответ

Предложенный вариант с storage работает только на одной и той де странице, то есть если открыть в нескольких табах page-1.php то предложенный вариант с window.addEventListener('storage', e => console.info('Changed')) сработает, иначе предлагаю сделать след. образом, как из ответа https://ru.stackoverflow.com/a/729727/243667
page-1.php
var storageParam = "name"; var defaultStorageVal = localStorage.getItem(storageParam); setInterval(function() { var val = localStorage.getItem(storageParam); if (val != defaultStorageVal) { document.getElementById("test-1").innerHTML=val; defaultStorageVal = val; // если alert один раз только должен сработать, убейте интервал } }, 500); // тут уже сами смотрите
page-2.php
localStorage.setItem("name", "text")

Есть ли разница в способах задания массива?

Эти две строки эквивалентны, или есть разница?
String[] dirNames = new String[] {"Dir_A","Dir_B","Dir_C","Dir_D","Dir_E"}; String[] dirNames = {"Dir_A","Dir_B","Dir_C","Dir_D","Dir_E"};


Ответ

Согласно спецификации
An array initializer creates an array and provides initial values for all its components.

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

Указатель на тип char, нюансы

Мне не понять
char *name[] = { "la la","la" }; cout << name << endl; // этот выдаёт адрес первого элемента
char *name1 = "la la"; cout << name1 << endl; // а этот самого "la la"
Почему первый вариант выдаёт адрес, а не полный строковый литерал "la la"? Ведь cout перегружен, так что вместо адреса выдаёт полное значение пока не встретит \0


Ответ

Потому что на самом деле name — это указатель на массив, а не указатель на char. Хотите вывести первый элемент массива — пишите
cout << name[0] << endl;

Определение объектов в C++

Добрый день, интересует такой вопрос, по поводу определения объектов в С++. Насколько я знаю объекты можно определять, как в стеке так и в куче. Знаю, что в стеке доступ к объектам будет быстрее, но если нужно будет запрашивать большое количество памяти, то нужно будет определять его в куче. Это в принципе все, что я знаю об этом. Хотелось бы услышать внятный ответ, когда и в каких ситуациях предпочтительнее тот или иной способ.


Ответ

Это в принципе все, что я знаю об этом. Хотелось бы услышать внятный ответ, когда и в каких ситуациях предпочтительнее тот или иной способ.
Введем для этого пояснения такое понятие, как время жизни объекта (object lifetime). Будем считать, что объект начинает жизнь тогда, когда под него выделилась память и завершилась его инициализация. Всякие отводы, тонкости и закавыки рассматривать не будем.
Объект умирает, когда память им занимаемая была освобождена или деструктор (если он есть и не тривиальный) объекта был вызван.
Итак, для начала рассмотрим коротенько четыре "времени хранения" (storage duration).
Статическое время хранения (static storage duration) - всё статическое живет от момента создания до самого конца программы.
Потоковое время хранения (thread storage duration) - всё потоковое живет от момента создания до конца потока в котором создано.
Автоматическое время хранения (automatic storage duration) - всё автоматическое живет от момента создания до конца блока в котором оно было создано.
Динамическое время хранения (dynamic storage duration) - всё динамическое живет от момента создания до того момента, пока его явно не прихлопнут.
Соответственно уже отсюда можно сделать вывод что нам необходимо.
A. Если объект должен жить всю программу (ну, почти), то варианта два:
Использовать объект с потоковым временем хранения, ежели у нас имеется один, живущий всю программу поток. Использовать объект с статическим временем хранения. Еще вариант, использовать динамический объект, но для его корректного уничтожения придется либо в какой-то из функций его явно уничтожить, что как бы уже подразумевает, что объект живет меньше чем статические объекты, либо же в деструкторе одного из статических объектов уничтожить и наш динамический объект, только вот получается, что нам для этого нужен статический объект, так что такой вариант не рассматриваем. Вариант не уничтожать его совсем - система прихлопнет память, рассматривать не будем, т.к. для объектов не будет вызван деструктор, а мы рассматриваем общее для всех объектов, а не отдельных их "видов". Так что для "чистоты эксперимента" подобные варианты мы не рассматриваем. Также выбросим из повествования временные объекты.
B. С потоковыми объектами, практически также, как и со статическими, только в масштабах потока, так что расписывать не буду, ибо и так ясно.
C. Если нам нужен объект, который должен быть уничтожен после выхода из блока, в котором создался, то варианта два:
Использовать автоматический объект. Использовать динамический объект, но при этом придется вручную его создавать и уничтожать.
D. Если нам необходимо, чтобы объект, созданный в блоке жил до самого конца программы (или потока),то вариант у нас один:
Сделать его статическим объектом, ну или потоковым, если речь о потоке. С динамическим объектом та же фигня, что и в прошлый раз - до конца такое не доживет, либо уничтожится не правильно (в общем случае).
E. Если нам необходимо, чтобы объект жил после выхода из блока в котором создан, но мы не знаем до какого времени он нам понадобится и, жить ему всю программу не нужно, то здесь вариант тоже один:
Динамический объект.
Теперь по каждому пункту отдельно.
A. Потоковый или статический? А смотрим на программу. У нас планируется всего один поток? Если да, то нефиг пытать потоковый класс памяти. Если же потоков может быть несколько, то у каждого потока должна быть своя такая переменная? Если да, то потоковый берем, если нет - статический.
B. см. предыдущий пункт.
C. Автоматический или динамический? Объекты маленькие, их количество известно и они точно влезут в стек (без фанатизма)? Если да то использовать автоматические объекты или динамические зависит от хотелок разработчика и здравого смысла. Если не нужна динамика, то нафиг заниматься ручной работой? Но если очень хочется, то можно хоть каждый int делать динамическим. Если же объекты тяжелые и не хочется на них тратить стек, или же нам неизвестно конечное количество одновременно живущих элементов, то тут только динамические объекты прокатят. Вариант "создам здоровый массив на все случаи жизни" здесь не прокатит, т.к. выше оговорено, что конечное количество одновременно живущих объектов неизвестно и, соответственно, оно всегда будет равно sizeof(mySuperArray)/sizeof(*mySuperArray) + 1
D. Всё как и прежде - смотрим на потребности в каждом потоке.
E. Без вариантов.
В программах, чаще всего, встречается смесь из всего высказанного выше в разных пропорциях и сочетаниях.
Вот такая абсолютно бесполезная портянка, т.к. она всё равно не покрывает всего и вся и не является истиной в последней инстанции.

Зачем нужен input type=“password”?

Я разумеется понимаю, что в новой версии HTML5 данное поле чётко указывают браузеру что мы в него прописываем именно пароль, и это вроде как, правильно с точки зрения SЕО, но меня интересует именно внутренняя сторона. Почему пароль не прописывать просто в поле input type="text", всё равно ведь сообщение до отправки на сервер не поддается шифрованию, обычно (если это форма регистрации), а так это только визуально скрытое маской поле


Ответ

Поле ввода типа "password" используется для тайного пользовательского ввода - вместо введёных символов на экране будут видны звёздочки или жирные точки, зависит от ОС и её настроек. В реальности при отправке формы данные будут отправлены как есть, открытым текстом без шифрования, если используется обычный HTTP.
Исторически сложилось так, что это поле часто использовали для ввода паролей для регистрации или входа на сайт. Исходя из этого многие браузеры предлагают всякие фишки при взаимодействии с таким полем:
Автоматическое запоминание и подстановку паролей, Предупреждение о незашифрованном соединении.

Сортировка массива. Нули, отрицательные, положительные

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


Ответ

Можно использовать такой вариант:
int a[] = {-8, 7, 0, 0, 6, 4, 17, -37, -178, -1, 0, 77}; a = IntStream.of(a).boxed().sorted( (x, y) -> x == 0 ? Integer.compare(x, Math.abs(y)) : y == 0 ? Integer.compare(Math.abs(x), y) : Integer.compare(x, y) ).mapToInt(Integer::intValue).toArray();
В случае, если один из аргументов равен нулю - сравнивать его с абсолютным значением другого аргумента. Таким образом нули будут в самом начале, а остальные значения будут отсортированы как обычно.
В случае, если не нужно сортировать числа в каждой из групп, можно воспользоваться более простым вариантом:
a = IntStream.of(a).boxed() .sorted(Comparator.comparing(i -> i == 0 ? -1 : i > 0 ? 1 : 0)) .mapToInt(Integer::intValue).toArray();

Почему 1 id перекрывает 11 классов?

bla bla


Ответ

CSS-селекторы имеют свой вес, который определяет как взаимодействуют одинаковые свойства, заданные в разных местах кода одному и тому же элементу.
Вес селекторов:
style="" — 1,0,0,0 #id — 0,1,0,0 .class — 0,0,1,0 [attr=value] — 0,0,1,0 LI — 0,0,0,1 * — 0,0,0,0
Примеры:
LI — 0,0,0,1 — селектор по тегу UL LI — 0,0,0,2 — селектор c двумя тегами весит больше, чем с одним. .orange — 0,0,1,0 — селектор с классом весит больше, чем селектор с тегом. .orange A SPAN — 0,0,1,2 — селектор перевесит предыдущий, потому что помимо класса содержит два тега. #page .orange — 0,1,1,0 — селектор с ID перевесит всё, кроме inline-стилей.
Есть еще !important, которым можно перебить даже inline стиль. Но обычно это нужно в крайних случаях. Если н используется часто, значит что-то сделано не так.

В целом, если у вас будет даже 156 классов подряд, то вес будет
0 0 156 0
что все равно никогда не побьет айдишник

P.S. Если интересно, можете поэкспериментировать с онлайн калькулятором весов селекторов

Порядок вывода foreach

Почему Foreach именно в таком порядке выводит объект?
A B Q
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class learningScript : MonoBehavior { public Hashtable inventory = new Hashtable();
void Start() { inventory.Add("age", "Q"); inventory.Add("gender", "A"); inventory.Add("name", "B"); foreach (string invert in inventory.Keys) { Debug.Log(inventory[invert]); } }
void Update() {
} }


Ответ

Это не foreach выводит, это Hashtable хранит. Эта коллекция не сохраняет порядок элементов. List порядок сохранит, SortedDictionary отсортирует, а хэш-таблицы сохранят в труднопредсказуемом порядке. Если важны и исходный порядок, и быстрый индексированный доступ, можно хранить в двух коллекциях сразу.

Внешний ключ между таблицами разных БД

Как создать внешний ключ между таблицами разных БД, которые находятся на одном сервере.СУБД: SQL SERVER


Ответ

читайте документацию
Ограничения FOREIGN KEY могут ссылаться только на таблицы в пределах той же базы данных на том же сервере. Межбазовую ссылочную целостность необходимо реализовать посредством триггеров. Дополнительные сведения см. в разделе CREATE TRIGGER (Transact-SQL)

rand() для переменных

Можно ли создать несколько переменных и при помощи функции rand() из этих переменных выбрать случайным образом одну?


Ответ

int a, b, c;
int& x = (rand() > 3000) ? a : (rand() < 2000) ? b : c;
Устроит?
Это если вам нужна именно переменная - с возможностью записи и т.д. Если ее значение - и того проще,
int x = (rand() > 3000) ? a : (rand() < 2000) ? b : c;
Естественно, rand() нужно использовать с умом; тут я привел просто для примера...
Это все имеет смысл, когда у вас уже есть переменные, из которых нужно делать выбор. Если вы сами их создаете... конечно, можно работать с массивом, вектором и т.д., но есть у меня подозрение, что это вопрос о том, какой рукой держать микроскоп при забивании гвоздей. Вам точно нужны именно переменные и выбор одной из них?

Программная перезагрузка Linux c помощью Python

В одном из моих мелких скриптов потребовалось реализовать программную перезагрузку компьютера под управлением Ubuntu. Не подскажите, как это проще всего сделать на Python? Скрипт работает не под рутом!


Ответ

Сделал, как мне рекомендовали:
softreset = subprocess.Popen(['systemctl', 'reboot'])

Сделать заглавными последние буквы каждого слова

Надо сделать заглавными последние буквы каждого слова. Но CodeHunt не считает мой код самым коротким. Как сделать еще короче?
public class Program {
public static String Puzzle(String s) { char[] chars = s.toCharArray(); for (int i = 0; i < chars.length; i++) { if (i==chars.length-1 || chars[i+1]==' ') chars[i]=Character.toUpperCase(chars[i]); }
return new String(chars); } }
Входные данные Выходные данные
"i " "I "
"aaaaaa" "aaaaaA"
" bbhbh" " bbhbH"


Ответ

Например, так:
char[] с = (s + " ").toCharArray(); for (int i = 1; i < с.length; i++) if (с[i]==' ') с[i-1]=Character.toUpperCase(с[i-1]); return new String(с);
Update
В условии выше не учитываются знаки препинания как разделители слов, то есть фраза "Вася,Петя,Сережа" будет одним словом, так как такие тестовые задания часто принимают пробел как единственные разделитель. Но если нужно учитывать знаки препинания, то используйте этот код (он будет считать разделителями все кроме букв и цифр):
char[] с = (s + " ").toCharArray(); for (int i = 1; i < с.length; i++) if ( !Character.isLetterOrDigit(c) ) с[i-1]=Character.toUpperCase(с[i-1]); return new String(с);

Преобразовать char* в массив double [C++]

Здравствуйте, задача состоит в следующем : Изначально нам дан массив double, который нужно зашифровать xor-ом, я привожу массив double к char массиву следующим образом:
unsigned char *char_from_double = reinterpret_cast(&doubleArr);
После этого прохожу по нему xor-ом, и на этом этапе возник вопрос, как его преобразовать обратно из char* в double массив? Просто привести char* к double массиву не получается
Как вариант, отдельно шифровать каждый элемент массива double, и хранить массив массивов char*, где один char* это одно double число, но подозреваю что это не очень хороший вариант


Ответ

Точно так же только наоборот. reinterpret_cast преобразует только укзатель, сам массив остается неизменным. Если у вас алгоритм шифорвания корректный то должно работать так:
double data_1[DATA_SIZE] = {...}; unsigned char * byte_array_1 = reinterpret_cast(&data_1[0]);
auto secret = encrypt(byte_array_1, DATA_SIZE * sizeof(double));
double data_2[DATA_SIZE] = {...}; unsigned char * byte_array_2 = reinterpret_cast(&data_2[0]);
decrypt(secret, byte_array_2, DATA_SIZE * sizeof(double));
double * data_2_pointer = reinterpret_cast(byte_array_2);
Но обычно так не делают как вы описываете. Под зашифрованные данные нужно выделить отдельный массив байтов и в него складывать зашифрованные данные, а исходный массив изменять не надо. Так принято не только для шифрования, а вообще для всех видов подобных обработок данный например сжатия.

Паттерн проектирования Future .Net C#

В книге Марка Гранда "Шаблоны проектирования" описан паттерн проектирования Future. Кто-нибудь использовал данный паттерн в C# и может объяснить в чем его суть?


Ответ

Суть паттерна заложена в его названии: future - будущее. Он означает, что создаётся задача, которая когда-либо в будущем вернёт результат.
Реализацией этого паттерна в .NET является класс Task. Что любопытно, изначально, на стадии разработки, он назывался Future, но позже был переименован. Тем не менее, артефакты остались: например, файл Future.cs в исходном коде.
Для подробного ознакомления смотрите документацию по библиотеке TPL, в частности, Futures
В современном C# есть ещё более удобные средства для работы с фьючерами - async/await