Страницы

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

вторник, 11 июня 2019 г.

Использование std::shared_mutex и проблема “обделения” писателя

Допустим, есть несколько читателей и один писатель, которые имеют общий ресурс, контролируемый посредством std::shared_mutex. Как быть в ситуации, когда читатели читают ресурс не одновременно, а, скажем, по очереди, т.ч. мьютекс всегда удерживается через std::shared_lock<>(), и писатель не может записать новые данные в ресурс, т.е. не может пробиться через инструкцию std::unique_lock<>?
Тут приходит на ум логика решения, что попытка захвата мьютекса писателем должна иметь более высокий приоритет, чем у читателей, т.е. когда писатель хочет что-то записать - он оставляет "заявление", т.ч. никакие читатели не могут сделать shared_lock, а те, что уже сделали - доделывают свою работу и ожидают обновлений со стороны писателя. Когда писатель обновит данные - может сделать notify_all() через condition_variable, к примеру.
Не вполне понимаю, как реализовать "приоритет захвата" в коде + может имеются другие решения данной проблемы не через std::shared_mutex?
P.S. Натолкнулся на описание в стандартах алгоритма Терехова, в котором говорится о прохождении читателей/писателей через двое входов, на основе которых выставляется приоритет. Но не совсем его понял. А именно, пройдет ли писатель первый вход, когда на втором есть читатели и, если так, то не смогут ли новые читатели зайти на вход 1.


Ответ

Не знаю, как с приоритетами, а идея двух входов довольно очевидна.
Все делают эксклюзивный lock на E1. Получив его, читатели делают shared lock на E2, а писатели эксклюзивный. Получив lock на E2 и читатели и писатель тут же освобождают lock на E1.
Таким образом, писатель прошедший E1 будет блокировать всех пришедших после него читателей до тех пор, пока последний из совместно использующих E2 читатель не освободит E2.

Изменение текстового поля на форме из потока (2 окна) QML QT C++

Пытаюсь изменить значение текстового поля из другого потока, но почему-то не работает: Есть 2 окна, первое окно:
firstwindow.h:
#include "mythread.h" #include
class FirstWindow : public QObject { Q_OBJECT public: explicit FirstWindow(QObject *parent = nullptr); private: MyThread *myThread; public slots: void start(); };
firstwindow.cpp:
#include "firstwindow.h"
FirstWindow::FirstWindow(QObject *parent) : QObject(parent) {
}
void FirstWindow::start() { myThread = new MyThread(5); //передача значения в класс MyThread }
firstwindow.qml:
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtQuick.Window 2.0
import FirstWindowModule 1.0
ApplicationWindow { visible: true width: 380 height: 240 id: firstwindow
FirstWindow { id: obj; }
//создание и вызов второго окна, вызов функции start(), создающей объект класса MyThread Button { text: "Start" onClicked: {
var component = Qt.createComponent("main.qml"); console.log("Component Status:", component.status, component.errorString()); var window = component.createObject(firstwindow); window.show()
obj.start(); } } }
Второе окно:
mythread.h:
#include "newclass.h" #include #include
class MyThread : public QObject { Q_OBJECT Q_PROPERTY(QString firstNumber READ GetFirstNumber WRITE SetFirstNumber NOTIFY firstNumberChanged)
private: QThread *thread; NewClass *newClass; QString firstNumber; int counter;
private slots: void UpdateFirstValue (int i); public slots: void StartThread(int); public: explicit MyThread(int value, QObject *parent = nullptr); explicit MyThread(QObject *parent = nullptr); QString GetFirstNumber(); void SetFirstNumber(QString);
signals: void firstNumberChanged(); };
mythread.cpp:
#include "mythread.h"
MyThread::MyThread(QObject *parent) : QObject(parent) { }
MyThread::MyThread(int counter, QObject *parent) : QObject(parent) { this->counter = counter; StartThread(counter); //запуск функции создания и запуска потока }
QString MyThread::GetFirstNumber() { return firstNumber; }
void MyThread::SetFirstNumber(QString value) { firstNumber = value; }
void MyThread::StartThread(int counter) { thread = new QThread; newClass = new NewClass(counter); newClass->moveToThread(thread);
connect(newClass, SIGNAL(sendfirstvalue(int)), this, SLOT(UpdateFirstValue(int))); connect(thread, SIGNAL(started()), newClass, SLOT(Start())); thread->start(); }
void MyThread::UpdateFirstValue (int i) { firstNumber = QString::number(i); emit firstNumberChanged(); }
main.qml:
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtQuick.Window 2.0
import NameModule 1.0
ApplicationWindow { visible: true width: 380 height: 240
Rectangle { id: content
TypeName { id: obj }
ColumnLayout { height: parent.height anchors.horizontalCenter: content.horizontalCenter Rectangle { Layout.fillHeight: true Text { anchors.centerIn: parent id: firstNumber text: "f = " + obj.firstNumber font.bold: true
onTextChanged: { console.log("firstNumberChanged"); }
} } } } }
Класс NewClass, функция которого работает в потоке:
newclass.h:
#include
class NewClass : public QObject { Q_OBJECT
public: explicit NewClass(int value, QObject *parent = nullptr); signals: void sendfirstvalue(int); private slots: void Start(); private: int value; };
newclass.cpp:
#include "newclass.h" #include #include "QDebug"
NewClass::NewClass(int value, QObject *parent) : QObject(parent) { this->value = value; }
void NewClass::Start() { qDebug() << "value" << value; for(int i = 0; i < value; i++) { qDebug() << "i" << i; emit sendfirstvalue(i); Sleep(1000); // from windows.h } }
Связка классов FirstWindow и MyThread с соответствующими им qml:
qmlRegisterType("FirstWindowModule", 1, 0, "FirstWindow"); qmlRegisterType("NameModule", 1, 0, "TypeName");
Суть проблемы: 2 окна, в первом окне (FirstWindow) располагается кнопка, по которой открывается второе окно (MyThread), и сразу запускается вычислительный процесс в новом потоке (функция Start() в классе NewClass. Данная функция в цикле, каждую секунду отсылает целочисленное значение обратно во второе окно MyThread, и данное значение должно отображаться в данном окне. Установлено, что проблема скорее всего в создании этого второго окна, что либо поток запускается раньше, чем показывается окно, либо еще что-то. Спасибо.
UPDATE: заново переписал вопрос и залил проект на https://github.com/sawyerhard/test2, Проблема не решена


Ответ

Проблема решена) В общем вся проблема была в этих 2х строчках в файле firstwindow.qml:
var window = component.createObject(firstwindow);
и вызов функции
obj.start();
при котором происходило повторное!!! создание объекта myThread, так как основной объект создавался в строчке выше (так как окно связано с MyThread классом), из-за этого данные, которые хоть и приходили, но не отображались в окне.
Решение: 1. Убираем строчку из firstwindow.qml:
obj.start();
2. Добавляем метод onCompleted в файл main.qml, в котором запускаем выполнение потока:
Component.onCompleted: { obj.startThread(5); }
Всем спасибо)

Проблема подключения моделей к html файлу

Здравствуйте, имеется bootstrap шаблон с блогом вот такого рода:
На скриншоте посты написаны от руки с применением html + css. Я работаю с Django и мне нужно сделать чтоб посты добавлялись автоматически, вместо тех, которые написаны от руки. Скажу сразу, в Django я новичок, модели для поста описал, но не получается прикрепить их к этому файлу.
пример моего файла models.py :
from django.db import models from django.utils import timezone
class Category(models.Model): name = models.CharField(max_length=128, unique=True)
class Meta: verbose_name_plural = 'Categories'
def __str__(self): return self.name
class Post(models.Model): category = models.ForeignKey(Category) author = models.ForeignKey('auth.User') title = models.CharField(max_length=128) text = models.TextField() views = models.IntegerField(default=0) likes = models.IntegerField(default=0) created_date = models.DateTimeField(default=timezone.now()) published_date = models.DateTimeField(blank=True)
def publish(self): self.published_date = timezone.now() self.save()
def __str__(self): return self.title
И пример views.py :
from django.shortcuts import render from .models import Post from django.utils import timezone
def index(request): return render(request, 'blog/index.html')
def post_list(request): posts = Post.objects.filter(published_date_lte=timezone.now().order_by('published_date')) return render(request, 'blog/index.html', {'posts': posts})
Вот еще кусочек html файл который отвечает за посты:


Technology

Lorem Ipsum is simply

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud eiusmod tempor incididunt ut labore et dolore magna aliqua exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Ut enim ad minim veniam, quis nostrud eiusmod tempor incididunt ut labore et dolore magna aliqua exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.



Пример всего html: ссылка
Таких кусков 5 штук, то есть 5 постов на странице. Я пытался удалить 4 последних, оставить один и немного изменить его, а именно:
{% for post in posts %}

{{ posts.category }}

{{ posts.title }}

{{ posts.text }}


{% endfor %}
Но все смещалось и я получал вот такой результат:
Посты зарегистрированы в админ панельке и я добавлял несколько штук через нее, но на сайте это никак не отображалось. Помогите пожалуйста, в чем причина? 2 день ломаю голову . Прощу прощения если описание получилось слишком большое :>


Ответ

У тебя в цикле {%for post in posts%}, необходимо использовать post.* , а не posts.*(post.title, post.text и т.п.). И возьми title ,category и text в один div, так проще редактировать. Также если у тебя много постов а нужно вывести только 5 используй {%for post in posts|slice:":5"%}

Символьные массивы.Обратный порядок слов

Ввожу предложение и на выходе хочу получить обратный порядок слов. Была идея сделать два массива. Оригинальный массив с предложением рассматривать с конца и записывать в новый массив ( где уже должен быть обратный порядок слов). Но с реализацией не вышло. Потом решил сделать по-другому
#include #include #include void main(void) { int i = 0, j = 0, k = 0, l = 0; char A[60]; gets_s(A); puts(A); l = strlen(A); while (l>=0) { j = j + 1; if (A[l] == 32) { while (k <= j) { printf("%c", A[l + ++k]);
} k = 0; j = 0; }
l--; } _getch(); }
Просто выводить на экран слова с конца , ориентируясь по пробелу


Ответ

Вот , заработало
#include #include #include void main(void) { int i = 0, j = 0, k = 0, l = 0, t = 0; char A[60]; gets_s(A); puts(A); l = strlen(A); while (l>=0) { j = j + 1; if (A[l] == 32 ) { while (k <= j) { printf("%c", A[l + k++]);
} k = 0; j = 0; } l--;
} while (A[t] != 32) t++; for (j = 0; j < t;j++) { printf("%c", A[j]); } _getch(); }
Додумался все-таки

Makefile: правильная пересборка .c файлов в случае изменения .h файлов:

Имеются файлы:
src1.c src1.h src2.c src3.c src4.c src4.h
Стоит обратить внимание, что НЕ для всех .c файлов есть свои .h файлы.
Текущий Мakefile работает, но с оговоркой: при изменении любого .h файла пересобираются ВСЕ .c файлы:
SRCS = $(wildcard *.c) HDRS = $(wildcard *.h)
%.o: %.c $(HDRS) @$(CC) -c -o $@ $<
Если раскрыть содержимое переменной $(HDRS), то автоматическая сборка будет выглядеть так:
%.o: %.c src1.h src4.h @$(CC) -c -o $@ $<
Именно поэтому, если изменился только один файл src4.h, то будут пересобраны все *.c файлы.
В другом случае, попытка сделать так, как указано в примере ниже, приведёт к ошибке, потому, что файлы src2.h src3.h не существуют:
%.o: %.c %.h @$(CC) -c -o $@ $<
Будьте любезны, подскажите, пожалуйста, как сделать правильный Makefile, чтобы при изменении src4.h пересобирался только src4.с, но не остальные.
Все мои самостоятельные попытки найти ответ на этот вопрос успехом не увенчались.
Заранее благодарю за совет.


Ответ

Можно указать зависимости в ручную в Makefile
src1.o: src1.c src1.h
и так далие для всех обектников
Или создать файлы зависимостей *.d для всех *.c файлов и включить в Makefile
SRCS = $(wildcard *.c) HDRS = $(wildcard *.h) OBJ_CATALOG=.obj/ OBJS=$(patsubst %.c,$(OBJ_CATALOG)%.o,$(SRCS)) DEPEND_CATALOG=.depend/ DEPEND=$(patsubst %.c,$(DEPEND_CATALOG)%.d,$(SRCS))
$(OBJ_CATALOG)%.o:%.c $(CXX) $(CFLAGS) -c $< -o $@
$(DEPEND_CATALOG)%.d:%.c $(CXX) -MM -I. $< | sed -e '1s/^/.obj\//' > $@
include $(DEPEND)

Jquery: почему не работает indexOf в массиве?

Есть массив, заполненный ячейками таблицы. Хочу, чтобы при клике на ту или иную ячейку мне возвращался её индекс в массиве. Но почему-то всегда возвращается -1. В чём здесь загвоздка?
var arr = []; $('td').each(function(){ arr.push($(this)); }); $('td').click(function(){ console.log(arr.indexOf($(this))); }); table { border-collapse: collapse; } table td { padding: 20px; text-align: center; vertical-align: middle; border: 1px solid black; }



Ответ

В вашем случае this - это элемент td. Замените $(this) на this
var arr = []; $('td').each(function(){ arr.push(this); }); $('td').click(function(){ console.log(arr.indexOf(this)); }); table { border-collapse: collapse; } table td { padding: 20px; text-align: center; vertical-align: middle; border: 1px solid black; }


Конструктор копии для классов

Пытаюсь присвоить значения вектора v1 k v2 но компилятор дает ошибку. Где ошибка? И ещё один вопрос, как перезагружать оператор присваивания ???
Process returned -1073741819 (0xC0000005) execution time : 1.253 s Press any key to continue.
Вот код
#include using namespace std; class vector_c { private: int* vector1; int Max; int index; public: vector_c(int sizze) { index=0; Max=sizze; vector1 = new int[Max]; };
vector_c(vector_c &c)//copy construck {
index=c.index; Max = c.Max; vector1 = new int[Max]; for (int i = 1; i <=Max; i++) { vector1[i] = c.vector1[i];
} }; ~vector_c() { delete [] vector1; }; void max_znachenie() { int index1=0; index1 = vector1[1]; for(int i=1; i<=Max;i++) { if(vector1[i] > index1 ) index1 = vector1[i]; } cout << index1 << endl; };
void get_inf(int element) { vector1[++index]=element; };
int out_inf() { return vector1[index--]; };
};

int main() { vector_c v1(3); v1.get_inf(78); v1.get_inf(2); v1.get_inf(5); v1.max_znachenie(); cout << endl; cout << endl << v1.out_inf() << endl << v1.out_inf() << endl << v1.out_inf() << endl; vector_c v2=v1; cout << v2.out_inf(); return 0; }


Ответ

Прогнала ваш код в дебаггере. Есть 2 проблемы. В конструкторе копирования копируются не все поля. Надо добавить.
index=c.index;
Функция переписана.
void get_inf(int element) { vector1[index++]=element; };
Пример перегрузки оператора присваивания
class vector_c { private: int* vector1; int Max; int index; public: vector_c(int sizze) { index=0; Max=sizze; vector1 = new int[Max]; };
vector_c& operator=(const vector_c& right) { //проверка на самоприсваивание if (this == &right) { return *this; } // Здесь скопируйте все значения return *this; } };

Проблема с фоном строк в Datagrid WPF

Имеется DataGridPeoples :

На котором возникает событие:
DataGridPeoples.Loaded += DataGridPeoples_Loaded;
Или
DataGridPeoples.LayoutUpdated
Следующего содержания:
private void DataGridPeoples_Loaded(object sender, EventArgs e) { foreach (People item in DataGridPeoples.ItemsSource) { var row = DataGridPeoples.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow; if (row != null && item.ExpirationDate.AddMonths(-1) <= DateTime.Now) { row.Background = Brushes.Crimson; } } }
Проблема заключается в следующем, при прокрутке формы цвет фона строк применяется к тем строкам к которым не должен применяться, насколько я понял проблема связана с виртуализацией, если сделать на Datagrid:
EnableRowVirtualization="False"
То все работает правильно, но работает очень медленно такой вариант меня не устраивает. Как можно реализовать окраску фона строк и виртуализацию в одном виде?


Ответ

В общем проблема решена в англоязычной ветке по следующей ссылке: https://stackoverflow.com/questions/17133286/rowvirtualization-cause-incorrect-background-color-for-rows. по умолчанию в Datagrid VirtualizationMode установлен как Recycling. Для решения этой проблемы рекомендуется установить VirtualizationMode в Standard

И изменить события для раскраски фона на DataGrid.LoadingRow
Надеюсь кому-нибудь поможет.

Чем посмотреть содержимое дампа полученного expdp Oracle?

Есть дамп выгруженный из БД Oracle. Как можно удобно посмотреть, какие объекты этот дамп содержит ?


Ответ

Воспользуйтесь параметром: sqlfile
impdp directory=expdir dumpfile=myexp.dmp sqlfile=ddl.sql

ListBox wpf SelectItem как получить в коде

ListBox lBox = new ListBox(); lBox.Items.Add("asdasd"); lBox.Items.Add("ыва23"); nb.Children.Add(lBox);
Как получить выделенный Item из списка?


Ответ

Используйте свойство SelectedItem, например:
MessageBox.Show((string)lBox.SelectedItem);

Для того, чтобы отслеживать смену текущего элемента, подпишитесь на событие SelectionChanged
lBox.SelectionChanged += lBox_SelectionChanged;
пример обработчика:
private void lBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { MessageBox.Show((string)lBox.SelectedItem); }

Кодировочка mariadb

Есть "замечательный" символ "🐉". И при попытке Insert его в таблицу получается, вот это:
ERROR 1300 (HY000): Invalid utf8mb4 character string: '\xF0\x9F\x90\x89'
Какая кодировка нужна?


Ответ

Подозреваю, что это ошибка на "стороне клиента".
Попробуйте:
SET NAMES utf8mb4;

MariaDB под рукой нет, вот как ведёт себя mysql:
mysql> describe Storage; +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | p | varchar(255) | NO | PRI | NULL | | | val | longtext | NO | | NULL | | +-------+--------------+------+-----+---------+-------+ 2 rows in set (0,00 sec)
mysql> INSERT INTO Storage VALUES('Dragon', '🐉'); ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x90\x89' for column 'val' at row 1 mysql> SET Names utf8mb4; Query OK, 0 rows affected (0,00 sec)
mysql> INSERT INTO Storage VALUES('Dragon', '🐉'); Query OK, 1 row affected (0,10 sec)
mysql> UPDATE Storage SET p = '🐉'; Query OK, 1 row affected (0,20 sec) Rows matched: 1 Changed: 1 Warnings: 0
mysql> SELECT * FROM Storage; +------+------+ | p | val | +------+------+ | 🐉 | 🐉 | +------+------+ 1 row in set (0,00 sec)

Расшифровать сообщение, зашифрованное с помощью разных систем счисления

1) 11 0F 13 10 29 1F 19 06 17 0E 01 20 02 06 08 0F 16 01 18 0E 15 12 19 1D
2) 18 18 09 13 28 03 01 0E 09 06
Известно, что при шифровании использовалось несколько систем счисления. Первое сообщение удалось расшифровать – «КОМПЬЮТЕРНАЯБЕЗОПАСНОСТЬ». Как расшифровать второе сообщение?


Ответ

Сообщения зашифрованы номером буквы в русском алфавите, и чередуются 10-чная и 16 ричная.
18 - десятичная. 18 буква это С
18 16-ричная, это 24 буква, это Ч
09 - 9 буква И
13 - 19 буква Т
28 - 28 буква Ы
03 - 3 буква В
01 - 1 буква А
0E - 14 буква Н 09 - 9 буква И 06 - Е
Итак, мы получили слово СЧИТЫВАНИЕ. Здесь Е=Ё, всего 32 буквы.

Воспользоваться функцией из другого cpp/h файла

Подскажите как объявить, и в последующем обратиться к функции в другом файле


Ответ

Во-первых, в .h-файлах нет никаких функций. Это просто кусок текста, вставляемый перед компиляцией вместо соответствующих директив #include. Соответственно, с точки зрения компилятора нет никакой разницы, включили ли вы заголовочный файл или просто взяли и скопировали его содержимое в свой .cpp руками.
То есть для решения вашей задачи нет разницы между заголовочным файлом с объявлением функции:
decl.h
#pragma once void foo(int bar); main.cpp
#include "decl.h" int main() { foo(21); // Использование функции } implementation.cpp
#include "decl.h" void foo(int bar) { // Реализация функции }
и повтором объявления в каждом .cpp-файле, которому нужна эта функция:
main.cpp
void foo(int bar); int main() { foo(21); // Использование функции } implementation.cpp
void foo(int bar) { // Реализация функции }
Во-вторых, .cpp-файл — это «вещь в себе», чёрный ящик с двоичными данными и списком того, что этот ящик импортирует/экспортирует, и по каким байтовым смещениям в вышеуказанных данных это требуется/реализуется соответственно:
Если в .cpp-файле производится обращение к чему-то, нереализованному в этом файле, и у компилятора есть объявление (то есть прототип для проверки корректности обращения), генерируется импорт этого чего-то по имени. Если в .cpp-файле объявляется не-static переменная либо функция (методы классов, кстати, тоже полноценные функции), генерируется экспорт.
И только потом, на этапе компоновки производится связывание соответствующих импортов и экспортов этих «чёрных ящиков» (а также подобных «ящиков», составляющих реализацию стандартной библиотеки).

Как поступить с translate?

Как можно при translate сдвинуть hidden элемент на его высоту ? Пояснения, имеем блок со скрытым содержимым которое скроллится при hover на высоту 100% но если высота разная то и работает не так как ожидается !
* { margin: 0; padding: 0: } .wrap { width: 500px; margin: 30px auto; display: flex; flex-direction: row; } .item { width: 250px; height: 250px; overflow: hidden; border: 4px double #ccc; margin: 10px; } .item1 { transition: transform 2s linear; height: 100%; } .item1 img { display: block; max-width: 100%; } .item:hover .item1 { transform: translate(0, -100%); }


Как можно исправить ситуацию ?


Ответ

Чтобы получить данный эффект:
добавляем transition на тэг img transform: translate(0, calc(-100% + 250px)); на .item:hover img - для прокрутки при наведении на окно. Чтобы вычислить высоту на которую нужно переместить img используем calc(-100% + 250px), где 250px - высота окна(.item)
* { margin: 0; padding: 0: } .wrap { width: 500px; margin: 30px auto; display: flex; flex-direction: row; } .item { width: 250px; height: 250px; overflow: hidden; border: 4px double #ccc; margin: 10px; } .item1 { height: 100%; } img { transition: transform 2s linear; } .item1 img { display: block; max-width: 100%; } .item:hover img { transform: translate(0, calc(-100% + 250px)); }


Ошибка: java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeCon

При попытке собрать проект возникает ошибка.
Код проекта:
fun main(args : Array) { println(“Hello”) }
Ошибка:
Error:Kotlin: [Internal Error] java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter at org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.parseMetadata(KotlinJavascriptMetadataUtils.kt:102) at org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils$loadMetadata$2.invoke(KotlinJavascriptMetadataUtils.kt:83) at org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils$loadMetadata$2.invoke(KotlinJavascriptMetadataUtils.kt:57) at org.jetbrains.kotlin.utils.JsLibraryUtils.traverseArchive(JsLibraryUtils.kt:182) at org.jetbrains.kotlin.utils.JsLibraryUtils.traverseJsLibrary(JsLibraryUtils.kt:54) at org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.loadMetadata(KotlinJavascriptMetadataUtils.kt:82) at org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.loadMetadata(KotlinJavascriptMetadataUtils.kt:90) at org.jetbrains.kotlin.js.config.JsConfig.checkLibFilesAndReportErrors(JsConfig.java:192) at org.jetbrains.kotlin.js.config.JsConfig.checkLibFilesAndReportErrors(JsConfig.java:150) at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:221) at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:83) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:103) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:51) at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:92) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$1.invoke(CompileServiceImpl.kt:380) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$1.invoke(CompileServiceImpl.kt:96) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:889) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:96) at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137) at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:916) at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:888) at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:378) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:355) at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200) at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196) at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:800) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:682) at java.base/java.security.AccessController.doPrivileged(Native Method) at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.base/java.lang.Thread.run(Thread.java:844)


Ответ

Проблема найдена, это оказывается баг Kotlin/JS компайлера c версией Java 9. Достаточно даунгрейдится до версии 8 или более ранних версий и все заработает ок.
демонстрация проблемы тут https://vimeo.com/238750933

Динамическое задание имени дефайна

Допустим у меня есть массив с числами
int numbers[] = {1, 2, 3, 4};
Мне нужно автоматически создать дефайны вида
#define DEF_[тут номер дефайна] [какое-либо число]
Конечный результат должен выглядеть следующим образом
#define DEF_1 42 #define DEF_2 54 #define DEF_3 45 #define DEF_4 98
Возможно ли это в C?


Ответ

Поскольку это средства препроцессора, т.е. выполняемые до компиляции, то и создавать их тоже нужно средствами препроцессора. Но динамическое создание директив препроцессора препроцессором же не предусмотрено. Да даже если бы и было предусмотрено - откуда брать ваши числа для макросов? Если препроцессор ничего о синтаксисе С вообще не знает?
Так что в лучшем случае - внешняя программа, которая будет это все либо дописывать в ваш файл, либо, что разумнее, создавать внешний, который можно включить через #include
Но я бы всерьез задумался над применением перечислений (enum), а не макросов...

Ошибка вывода данных из servlet в JSP

проблема следующая, пытаюсь отобразить данные переданные как список "List". Но получаю ошибку
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/servlet/jsp/jstl/core/LoopTagSupport
С чем связанно тоже не могу понять. Вот код servlet:
List list = new ArrayList();
while (resultSets.next()) { Roll roll = new Roll();
roll.setNumbern(resultSets.getInt(1));
roll.setRollnum(resultSets.getInt(2));
roll.setTimer(resultSets.getDate(4));
list.add(roll);
request.setAttribute("name",list); } request.getRequestDispatcher("4kl/test.jsp").forward(request, response);
Вот JSP
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ${n.Numbern} ${n.Rollnum} ${n.Timer}
Класс Roll
public class Roll implements Serializable { private static final long serialVersionUID = 1L;
private int Numbern;
private int Rollnum;
private Date Timer;
public int getNumbern() { return Numbern; }
public void setNumbern(int numbern) { Numbern = numbern; }
public int getRollnum() { return Rollnum; }
public void setRollnum(int rollnum) { Rollnum = rollnum; }
public Date getTimer() { return Timer; }
public void setTimer(Date timer) { Timer = timer; }
public Roll (){}
}
Pom.xml:
4.0.0
ua.asutp mymvn 0.0.1-SNAPSHOT war
javax.servlet servlet-api 3.0-alpha-1 provided
org.glassfish.main.extras glassfish-embedded-all 3.1.2.2 test
javaee javaee-api 5
jstl jstl 1.2
javax javaee-web-api 6.0 provided
local-oracle ojdbc6
org.hibernate hibernate-core 4.1.11.Final
dom4j dom4j 1.6.1
commons-logging commons-logging 1.2
commons-collections commons-collections 3.2.1
cglib cglib 2.2
javax.transaction jta 1.1

org.apache.maven.plugins maven-compiler-plugin 1.5 1.5
org.apache.maven.plugins maven-war-plugin 2.1.1 false

Возможно я что-то пропустил при вызове c:forEach Помогите пожалуйста разобраться. Может есть способ получше JSTL ? Я только учусь, поэтому мне хотелось бы знать как правильнее выводить данные. Спасибо. Все еще актуально.


Ответ

Не ответ, просто пометка:
request.setAttribute("name",list);
эту строчку вытащите из цикла,добавить то надо всего 1 раз

Ещё один момент по поводу зависимости
javax.servlet servlet-api 3.0-alpha-1 provided
в центральном репозитории я не смог найти такого, попробуйте взять более новую версию, например 4:
javax.servlet javax.servlet-api 4.0.0 provided
эту зависимость тоже стоит обновить. Нет такой версии 5, может быть где-то есть 5,0 но по идее это вам должна была IDE показать
javax javaee-api 7.0 provided

Репозиторий не содержит файла Release

Версия ОС Ubuntu 16.04.3 LTS
Поставил из deb файла приложение pomodoro. Чтобы получать обновление для программы, по инструкции с сайта, добавил репозиторий:
curl -L https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04/Release.key | sudo apt-key add - sudo sh -c "echo 'deb https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04/ /' >> /etc/apt/sources.list.d/gnome-pomodoro.list"
На попытку получить данные о пакетах apt-get update отвечает:
W: Репозиторий «https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04 Release» не содержит файла Release. N: Данные из этого репозитория нельзя аутентифицировать, и поэтому потенциально из небезопасно использовать. N: Смотрите справочную страницу apt-secure(8) о создании репозитория и настройке пользователя. E: Не удалось получить https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04/Packages Protocol "http" not supported or disabled in libcurl E: Некоторые индексные файлы не скачались. Они были проигнорированы или вместо них были использованы старые версии.
При этом в логе все записи относящиеся к целевому репозиторию имеют вид:
Игн:10 https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04 Translation-en
Смотрел похожие вопросы, (например), но это решение мне не подходит судя по всему. По предлагаемой в том топике команде tail -n 100 /etc/apt/sources.list /etc/apt/sources.list.d/*; lsb_release -a получаю следующее (комментарии удалил):
==> /etc/apt/sources.list <== deb http://ru.archive.ubuntu.com/ubuntu/ xenial main restricted deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates main restricted deb http://ru.archive.ubuntu.com/ubuntu/ xenial universe deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates universe deb http://ru.archive.ubuntu.com/ubuntu/ xenial multiverse deb http://ru.archive.ubuntu.com/ubuntu/ xenial-updates multiverse deb http://ru.archive.ubuntu.com/ubuntu/ xenial-backports main restricted universe multiverse deb http://archive.canonical.com/ubuntu xenial partner deb http://security.ubuntu.com/ubuntu xenial-security main restricted deb http://security.ubuntu.com/ubuntu xenial-security universe deb http://security.ubuntu.com/ubuntu xenial-security multiverse
==> /etc/apt/sources.list.d/gnome-pomodoro.list <== deb https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04/ / No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.3 LTS Release: 16.04 Codename: xenial


Ответ

при обращении по указанному адресу сервер возвращает 301-й код — перенаправление на правильный адрес (у которого перед именем репозитория указан слэш):
$ curl -s -D - -o /dev/null 'https://download.opensuse.org/repositories/home:kamilprusko/xUbuntu_16.04/Release' HTTP/1.1 301 Moved Permanently Date: Wed, 18 Oct 2017 15:42:36 GMT Server: Apache/2.2.34 (Linux/SUSE) Location: http://download.opensuse.org/repositories/home:/kamilprusko/xUbuntu_16.04/Release Content-Length: 381 Content-Type: text/html; charset=iso-8859-1
именно так (/kamilprusko, а не kamilprusko) должен быть указан путь к репозиторию в obs-e
см. пример в документации: https://en.opensuse.org/openSUSE:Build_Service_Debian_builds#Configuring_sources.list
если в файл /etc/apt/sources.list.d/*.list внести такое исправление, то apt нормально получит всё, что запрашивает у сервера.

доп. информация: apt does not handle HTTP redirects

Поиск индекса в List

Есть класс:
public class ProductPit { public ProductPit(string prod, double cena, string ediz) { Prod = prod; Cena = cena; EdIz = ediz; }
public string Prod { get; set; } public double Cena { get; set; } public string EdIz { get; set; } }
Я создаю список с элементами ProductPit
List prpit = new List;
Как мне в списке найти номер записи в которой: prpit.Prod == "Колбаса" Знаю что есть IndexOf, но как его использовать в данном случае не пойму(


Ответ

Воспользуйтесь методом FindIndex()
Он принимает предикат, которой проверит ваше условие:
int index = list.FindIndex(x => x.Prod == "Колбаса");

Разница между типами методов private and protected

Пытаюсь разобраться в чем разница между private and protected в Ruby, но как то не очень получается. Из того что я понял, это то что приватный метод нельзя явно вызвать на экземпляре класса и он может быть вызван только другими методами этого же класса. А вот протектед вроде как можно вызвать явно, но в то же время и публичный метод можно вызвать явно, и он является чем-то средним между публичным и приватным. Так в чем же особенность протектеда, и где его следует использовать, можете мне объяснить (желательно с реальным примером). Буду очень благодарен.
UPDATE
И еще вопрос "вдогонку", private and private_class_method тоже не совсем понятна разница. Private это как методы класса, а private_class_method методы экземпляра, но ведь ни те ни другие не могут быть вызваны явно ни на чем кроме как методы в классе.


Ответ

Это не относится только к Ruby. Это относится ко всему ООП в целом.
Приватный метод (свойство) (он же private) - такой метод (свойство), доступ к которому можно получить только из того же класса (или объекта того же класса).
Защищенный метод (свойство) (он же protected) - такой метод (свойство), доступ к которому можно получить только из того же класса (или объекта того же класса) и из его наследников.
Публичный метод (свойство) (он же public) - такой метод (свойство), доступ к которому можно получить откуда угодно - извне определенного класса, из объекта определенного класса, из наследников.
А вот протектед вроде как можно вызвать явно
Нет, защищенные методы "защищены" от доступа извне, они являются приватными с той оговоркой, что к ним есть доступ у наследников класса, как уже было сказано выше. Разрешать доступ защищенному методу (свойству) извне не имеет смысла, так как такой метод (свойство) по определению станет публичным.
Про "вопрос вдогонку":
Не совсем понятно, о каких private_class_method идет речь. Если о статических методах и свойствах, то ограничение публичности предусмотрено для тех же целей.
Например, в статическое поле класса можно "сохранять" экземпляры, созданные конструктором этого же класса. При этом мы не хотим, чтобы пользователь имел доступ к списку созданных экземпляров извне, откуда-то снаружи, потому как этот список необходим только для какой-то сложной логики при создании экземпляра, например. А вот иметь возможность записывать в это свойство экземпляры внутри, скажем, конструктора, мы хотим. Поэтому делаем статическое свойство приватным, и тогда, например, из конструктора, у нас есть возможность сохранить экземпляр в свойство (назовем его instances), и из других методов класса его прочитать можем, а вот "снаружи" к нему обратиться (прочитать, записать) нельзя.
Вдобавок, пожалуй, стоит уточнить, что все методы (свойства) нужно делать максимально защищенными. Это хорошая практика. Делайте публичными только те свойства, к которым придется обращаться снаружи. Не оставляйте "служебные" свойства и методы публичными, поскольку вы никогда не можете знать, как их будут впоследствии использовать.

set -o vi при подключении по ssh

Подскажите пожалуйста, можно ли добавить настройку на мой VPS таким образом, чтобы при подключении по ssh по умолчанию загружался bash c set -o vi и мне не надо было прописывать его вручную?
Операционная система на VPS - Ubuntu Linux.
Спасибо


Ответ

Есть несколько способов сделать это:
Добавить команду в ~/.bashrc Тогда при стратке консоли выполняется ~/.bashrc для данного пользователя Создать /etc/profile.d/myCommands.sh прописать туда нужные вам команды. Будет выполняться для всех пользователей. Добавить выполнения команды в /etc/bashrc Будет выполняться для всех пользователей.
Я рекомендую воспользоваться 1 пунктом. Но если вам надо, чтобы это работало под другими пользователями, например, root, то воспользуйтесь 2 или 3 пунктами.

Загрузка файлов на сервер Node без использования Express и др. модулей

Изучаю Node. Хочу разобраться как происходит загрузка файлов на сервер и что для этого надо. Гуглил, но везде используются Express и другие модули. У меня получается загрузить данные, но они записываются в формате "base64" и файл становится не читабельным. Использую вот такую конструкцию:
var data =""; req.on('data', function(chunk){ data += chunk; }) req.on("end", function(){ fs.writeFile("000.txt", data, function(err){ if (err) console.log("Ошибка записи"); })


Ответ

Для записи раскодированных данных в файл есть несколько вариантов. Самый простой для вашего примера - это добавить дополнительный параметр функции writeFile, который указывает кодировку данных:
fs.writeFile("000.txt", data, 'base64', function(err){
при этом данные будут записаны в файл в раскодированном виде.

Пользовательский конструктор копирования/перемещения

Правильно ли я понимаю, что будет плохой техникой реализовывать конструкторы копирования/перемещения, используя соответствующие операторы присваивания?
Т.е. лучше ли использовать списки инициализации, соответственно, в случае перемещения в них надо указывать дополнительно при надобности приведение к rvalue с помощью std::move(), а в теле перемещающего конструктора «обнулить» rhs (это по соглашению проекта)? Ну и какие-то дополнительные операции в теле, например, копирование поэлементное массива или логирование.


Ответ

Вообще говоря, да, это будет странной техникой.
С общей точки зрения попытки реализовать конструктор копирования через копирующий оператор присваивания будут страдать от проблемы "двойной инициализации": так как оператор присваивания ожидает на вход уже сконструированные объекты, в конструкторе придется сначала конструировать какой-то (пустой) объект, а лишь затем вызывать для него оператор присваивания, который будет "переконструировать" этот объект по-новому.
В устоявшихся идиомах обычно делают наоборот: копирующий оператор присваивания реализуется через конструктор копирования. Так это делается, например, в известной идиоме Copy-And-Swap.

Проектирование кода: использование return в switch

Какой код с точки зрения проектирования более правильный
Такой:
public List getStringList(int expression){ List list;
switch(expression){ case 1: list = getList1(); break; case 2: list = getList2(); break; ... } return list; }
Или такой:
public List getStringList(int expression){ switch(expression){ case 1: return getList1(); case 2: return getList2(); ... } }
В данный момент мы никак не изменяем и не предопалагаем, что нам нужно изменять список list в функции getStringList
Хотелось бы прочитать обоснованный ответ в пользу того или иного варианта.
В первом случае у нас одна точка выхода их функции, в switch мы только присваиваем переменную, которую возвращаем, а во втором случае у нас получается несколько точек выхода.


Ответ

В языках с RAII или try/finally нет никакого правила, по которому предпочтительнее единственная точка возврата из функции. Поэтому писать надо так, как легче читать, никакого другого правила тут нет.
В вашем случае, как мне кажется, введение дополнительной переменной служит только цели единственной точки возврата в функции, так что я бы предпочёл более короткий вариант с return из середины switch. Введение дополнительной переменной заставляет читателя помнить о результате до конца switch'а, и держать наличие его в голове, в то время как ранний return позволяет сразу отбросить этот случай.
Но это, снова-таки, вопрос личных литературных предпочтений. Пишите, как вам кажется лучше.

C# вопрос по потокам для изучения

Уважаемы гуру, есть вопрос. Хочу изучить потоки и не пойму с чего начать, а может что то и вообще не нужно для изучения или устарело.
Не вникая, быстро пробежался по поиску и наткнулся сначала на "Thread", затем увидел какой то "Task" , а ещё и на stackoverflow подкинули "async/await"
Может кто то направить на правильный путь для изучения потоков ?


Ответ

Потоки (в смысле "одновременно выполняющиеся куски кода") - это именно Threads.
Task - это чуть более высокий уровень абстрации. Это способ организовать работу в виде отдельных кусков (Task), которые могут, в том числе, представлять из себя одновременно выполняющиеся части кода. А могут представлять из себя что-то, что к выполнению кода вообще отношения не имеет - например, "задача чтения с диска", или "задача ожидания 10 секунд". Т.е. Task-и - это объединение идей параллельности (потоков) и асинхронности (каких-то долгих операций, о завершении которых приходит отдельное уведомление).
async / await это механизим языка, облегчающий работу с Task. Т.е. это способ красиво писать код с Task-ами (если не вдаваться в подробности).
Я бы посоветовал вам почитать про обычные потоки (Threads), хотя бы на уровне "как запустить", "как остановить", "как запустить кусок кода на потоке из Thread Pool". Потом почитать про таски, понять разницу между асинхронностью и многопоточностью, и начать писать код сразу с async / await

WPF как очистить Source у Image Control

Мне нужно загружать картинку из бд и отображать ее на екране в контроле Image, после чего в определенном моменте мне нужно очищать Source тоесть путь к картинке что бы ее удалить и загрузить новую.
Свойство прибинденное к Source у Image:
private string photo; public string Photo { get { return photo; } set { photo = value; OnPropertyChanged("Photo"); } }
Очищаю путь к картинке и загружаю новую из бд:
// пытаюсь заставить сбросить путь Photo = null; // при попытке удаление вылазит ошибка "невозможно удалить так как используеться другим процесом" File.Delete(Environment.CurrentDirectory + "\\Photo.png"); // загрузка картинки з бд на форму if (SelectedVerstatOperator.Photo != null) { ImageLoadFromDataBase(SelectedVerstatOperator.Photo); }
Метод ImageLoadFromDataBase:
private void ImageLoadFromDataBase(byte[] image) { using (var ms = new MemoryStream(image)) { // создаю новую картинку var photo = System.Drawing.Image.FromStream(ms); // сохраняю ее на диск photo.Save(Environment.CurrentDirectory + "\\Photo.png"); // задаю путь к картинке для отображения в Image Photo = Environment.CurrentDirectory + "\\Photo.png"; } }
Как заставить Image оставить в покое картинку? Что бы я ее удалил


Ответ

Решил так. Сохраняю картинку с рандомным именем в папку Temp
private void LoadImageFromDataBase(byte[] image) { using (var ms = new MemoryStream(image)) { var photo = System.Drawing.Image.FromStream(ms); string randomFileName = Path.GetRandomFileName(); randomFileName = randomFileName.Replace(".", ""); var path = Environment.CurrentDirectory + "\\Temp\\" + randomFileName + ".png"; photo.Save(path); Photo = path; } }
А при закрыти программы удаляю папку Temp и заново создаю ее
string dir = System.Environment.CurrentDirectory + "\\Temp"; System.IO.Directory.Delete(dir, true); System.IO.Directory.CreateDirectory(dir);

Обработка события нажатия правого клика мыши по кнопке

Только недавно начал разбираться с WinApi, и в процессе решения лабораторной возник вопрос: как обработать нажатие правой кнопки мыши по отдельно взятой кнопки окна? Событие WM_RBUTTONDOWN определяет нажатие правой кнопки мыши по всему окну, поэтому оно мне не подходит. Если не затруднит, можете предоставить пример кода, а то я только начинающий. Заранее благодарю за ответ.


Ответ

Вообще, подобный подход (использование правой кнопки мыши на кнопке) является плохой практикой в разработке GUI, так как нарушает ожидаемое пользователем поведение кнопки.
Если кнопка подразумевает дополнительный набор связанных с ней действий, используйте кнопку с маленькой кнопочкой-стрелкой на её правой стороне (такие имеют оконный класс BS_SPLITBUTTON, либо BS_DEFSPLITBUTTON):
    
Если же вам по какой-то причине нужна обработка именно правой кнопки мыши (и я очень надеюсь, что это учебное задание, а не реальная разработка), то единственный способ пойти против рекомендаций Microsoft — перехватывать («сабклассить») нужное вам оконное сообщение WM_RBUTTONDOWN
#include #include #include
// Указатель на исходный обработчик кнопки WNDPROC oldButtonProc;
// Обработчик нажатия правой кнопки мыши // Замечание: bDblCkick всегда равен FALSE static void onRButtonClick(HWND hwnd, BOOL bDblClick, int x, int y, UINT uKey) { // ... }
// Перехватчик static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { // Обрабатываем WM_RBUTTONDOWN, а остальное передаём обработчику кнопки по умолчанию // Для удобства воспользуемся message crackers из switch(uMsg) { HANDLE_MSG(hwnd, WM_RBUTTONDOWN, onRButtonClick);
default: return oldButtonProc(hwnd, uMsg, wParam, lParam); } }
// Где-то в коде надо назначить наш обработчик нужной кнопке следующим образом // (для удобства оформил всё в отдельную функцию. hButtonWnd — hwnd нужной кнопки): void subclassButton(HWND hButtonWnd) { // Преобразуем типы без нарушения strict aliasing rule const WNDPROC newProc = WindowProc; LONG_PTR newValue; #if __cplusplus >= 201103L static_assert(sizeof(newValue) == sizeof(newProc), "incompatible conversion"); #endif memcpy(&newValue, &newProc, sizeof(newProc));
const LONG_PTR oldValue = SetWindowLongPtr(hButtonWnd, GWLP_WNDPROC, newValue);
#if __cplusplus >= 201103L static_assert(sizeof(oldButtonProc) == sizeof(oldValue), "incompatible conversion"); #endif memcpy(&oldButtonProc, &oldValue, sizeof(oldValue)); }

Обведение контура здания тапом

Привет. Подскажите, пожалуйста, каким образом я могу выделить здание в Google Maps в своём приложении. Конкретно, я тапаю на здание, оно автоматически проводит линию по контуру данного здания. Спасибо


Ответ

Не думаю, что будет проводить линию красиво и с анимацией, но такая возможность есть и официальна.
Вам нужно изучить Импорт данных KML на карту
Эта служебная программа позволяет преобразовывать объекты KML в географические фигуры и добавлять их в виде слоя поверх карты. Чтобы добавить слой к карте, вызовите метод addLayerToMap(). Доступ к свойствам объекта KML можно получить путем вызова метода getProperties() для любого объекта Placemark, GroundOverlay, Document или Folder. Дополнительные сведения см. в документации для служебной программы Google Maps Android KML.
Пример от Google на Github
Примечание. В настоящее время эта служебная программа доступна в бета-версии. Чтобы сообщить о возникших проблемах или выявленных ошибках, воспользуйтесь системой отслеживания проблем.

P.S. В любом случае, есть куда копать

Почему при индексах [1],[2] и [-1],[-2] дает одинаковые результаты

>>> c=bob[0].split() >>> c ['Bob', 'Smith'] >>> c[1] 'Smith' >>> c[0] 'Bob' >>> c[-1] 'Smith' >>> c[-2] 'Bob'


Ответ

Некоторые типы в Python вроде списков и строк поддерживают отрицательные индексы. Они позволяют брать элементы с конца: c[-1] это последний элемент, c[-2] предпоследний и так далее. Отрицательные индексы можно переписать на вычисление положительного индекса, примерно так: c[len(c) - 1], c[len(c) - 2] и так далее.
В документации Python есть наглядная диаграммка, показывающая, как нумеруются символы в строке (для списков тоже применимо):
+---+---+---+---+---+---+ | P | y | t | h | o | n | +---+---+---+---+---+---+ 0 1 2 3 4 5 6 -6 -5 -4 -3 -2 -1
Тем не менее, проверка на выход за пределы списка/строки всё ещё имеется:
>>> s = 'Python'
>>> s[6] Traceback (most recent call last): File "", line 1, in IndexError: string index out of range
>>> s[-7] Traceback (most recent call last): File "", line 1, in IndexError: string index out of range
Кстати, с помощью расширенного синтаксиса срезов можно перевернуть список, если указать отрицательный шаг:
>>> c = ['Bob', 'Smith'] >>> c[::-1] ['Smith', 'Bob']

Рывки объекта при быстром движении Unity

Объект движется на wheel collider'ах, при наборе скорости больше 10 единиц в секунду, объект начинается двигаться рывками, убрав вертикальную синхронизацию и ограничив число кадров до 50, получилось снизить кол-во фризов, но все же они остались. Т.к. объект движется на вилах, расставить time.deltaTime не получится.


Ответ

Попробуйте уменьшить интервал обновления физики в настройках проекта в Time Manager. Вполне возможно, что при определенной скорости ваш объект передвигается слишком быстро, чтобы физика успевала корректно обрабатывать эти перемещения. Вам нужно изменить величину Fixed Timestep, от которой зависит частота обновления, так же на нее будет завязано с какой частотой у вас будет вызываться метод FixedUpdate() в ваших скриптах. Немного подробней об этом можно почитать здесь
P.S. Если ваша проблема действительно заключается в физике, то изменение количества FPS не сильно вам поможет, так как физика в Unity работает отдельным потоком и обновляется по отдельному таймеру с фиксированным шагом, в отличии от графики.

Как сделать скриншот окна?

Надо сделать скриншот отдельного окна на экране. Допустим калькулятора. c#


Ответ

К сожалению, я не смог найти решение совсем без P/Invoke. Вы должны найти нужный процесс (обычно он у вас и так есть, раз вы за ним следите), его окно (например, у класса Process можно опросить MainWindowHandle), и у этого окна взять его координаты на экране. Для этого придётся вызывать WinAPI-функцию GetWindowRect
using System.Drawing;

[DllImport("user32.dll", SetLastError = true)] static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
Скопировать кусок экрана можно при помощи функции Graphics.CopyFromScreen, которая доступна в WinForms. Если у вас не WinForms-приложение, придётся подключить System.Drawing.dll
Получаем такой вот код:
var process = Process.GetProcessesByName(тут имя процесса).FirstOrDefault(); // не забудьте поверку ошибок: вдруг у вас не нашлось ни одного процесса? GetWindowRect(process.MainWindowHandle, out var rect); using (var image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top)) { using (var graphics = Graphics.FromImage(image)) graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, image.Size);
// тут у вас есть картинка, вы можете, например, сохранить её image.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png); }
У меня получился вот такой скриншот окна Visual Studio:

Недостатки метода:
окно должно быть на переднем плане, иначе вы получите перекрытые части могут быть проблемы с Aero-интерфейсом (вот тут решение, которое умеет бороться с этой проблемой, но я не проверял)

Обновление:
Я нашёл вот тут решение, которое обходит первую проблему, то есть, умеет делать снимок окна, не находящегося на переднем плане. Для этого мы должны использовать ещё одну WinAPI-функцию PrintWindow. Вот улучшенный код:
using System.Drawing; using System.Drawing.Imaging;

[DllImport("user32.dll", SetLastError = true)] static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
[DllImport("user32.dll")] static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, int nFlags);
[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }

var process = Process.GetProcessesByName(тут имя процесса).FirstOrDefault(); // не забудьте поверку ошибок: вдруг у вас не нашлось ни одного процесса? var hwnd = process.MainWindowHandle; GetWindowRect(hwnd, out var rect); using (var image = new Bitmap(rect.Right - rect.Left, rect.Bottom - rect.Top)) { using (var graphics = Graphics.FromImage(image)) { var hdcBitmap = graphics.GetHdc(); PrintWindow(hwnd, hdcBitmap, 0); graphics.ReleaseHdc(hdcBitmap); }
// тут у вас есть картинка, вы можете, например, сохранить её image.Save(imagePath, ImageFormat.Png); }

e.printStackTrace() заменяет throw?

Часто встречаю подобный код:
Scanner in = null;
try { in = new Scanner(new File(FILE_NAME)); } catch (FileNotFoundException e) { e.printStackTrace(); }
if (in.hasNext()) {
В случае исключения вызовется e.printStackTrace();, что выведет ошибку в stderr, но ведь дальнейшее выполнение метода продолжится с некорректным состоянием?


Ответ

Представленный в вопросе код плох в любом случае:
Если исходное исключение важно (например, этот метод в библиотеке и вызывается извне), то, вероятно, разработчики, использующие эту библиотеку, "отвесят низкий поклон" её создателям за невозможность обработать исключение так как им надо и за довольствование stacktrace-ом в stderr Если исключение не важно (важен только результат), то тут всё равно вместо результата будет NullPointerException, который ещё и непонятно на каком уровне будет обработан. Даже если вызывающая сторона обладает знанием (из документации или магическим образом) того что нужно отлавливать NullPointerException и показывать при этом пользователю сообщение "Файл не найден", то при наличии в методе других потенциальных мест возникновения NullPointerException, эта логика рискует оказаться сломанной

К каким выводам можно прийти:
Если метод используется в библиотеке, то имеет смысл пробрасывать исходное исключение (возможно, в какой-то обёртке). Даже если с точки зрения бизнес-логики важен только результат, то для отладки исключение вполне может понадобиться Если метод является внутренним для программы, то тут уже "на вкус и цвет". Где-то имеет смысл "проглотить" исключение и сделать в catch, например, return null (или дальнейшую логику с in обернуть в if (in != null), если возникшее исключение - ещё не повод прекращать работу метода), где-то - пробросить вверх и обработать, например, глобально

C++ open разных файлов, возвращает одинаковый дескриптор

Здравствуйте, пытаюсь в линуксе перечислить доступные порты. Находит два, но при этом почему то возвращает одинаковые дескрипторы, хотя программа не закрывает файлы.
printf("Ports enumeration:
");
int portDesc; std::string pathBasis = "/dev/ttyS"; for (uint counter = 0; counter <= 64; counter++) { std::string searchString = pathBasis; searchString += std::to_string(counter); portDesc = open(searchString.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); if (portDesc != -1) { printf("%s%s%s%x%s","Found serial port: ", searchString.c_str(), "
Port descriptor: ", std::to_string(portDesc), "
"); } }


Ответ

Вам надо заменить строчку
printf("%s%s%s%x%s","Found serial port: ", searchString.c_str(), "
Port descriptor: ", std::to_string(portDesc), "
");
на
printf("%s%s%s%x%s","Found serial port: ", searchString.c_str(), "
Port descriptor: ", portDesc, "
");
Потому как вы преобразовываете дескриптор в строку, а потом зачем-то выводите ее как целое шестнадцатеричное число (формат %x) - вот в этом косяк. У вас выводится не дескриптор - а не понятно что.
А еще лучше - на
printf("Found serial port: %s
Port descriptor: %x
", searchString.c_str(), portDesc);
А еще лучше - юзать потоки ввода-вывода стандартной библиотеки, чтобы так не попадать.

Регулярное выражение для поиска подстроки из символов в строке

Есть регулярное выражение ^(\d{4,7})$ Оно валидно для поиска строки вида 123456, на данную строку оно реагирует положительно. Но как модифицировать данную регулярку, чтобы найти подобную подстроку 123456 в строке вида:
Вася сегодня съел 123456 яблок
Я пытался добавить * в конце регулярки, но не помогло. Подскажите, что не так, в регулярках не силён, словарик не помог. Всем заранее спасибо.


Ответ

Используйте границу слова
String regex = "\\b\\d{4,7}\\b";
Или блоки предварительного просмотра вперёд/назад:
String regex = "(?Если шаблон \b стоит перед \d, то перед цифрой не должно быть буквы, цифры или знака подчёркивания. Если шаблон \b стоит после \d, то после цифры не должно быть буквы, цифры или знака подчёркивания.
Блок предварительного просмотра назад (?Демо-код на Java
String s = "Вася сегодня съел 123456 яблок"; String regex = "\\b\\d{4,7}\\b"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(s); while (matcher.find()){ System.out.println(matcher.group(0)); } // => 123456

Поиск данных по введенному ключу

Задание:
"Вывести на экран пункты назначения и номера маршрутов обслуживаемых автобусов, марка которых введена с клавиатуры. Если таких нет, вывести на экран соответствующее сообщение".
Я вроде бы это реализовал, но выдает не найдено; я понял где у меня ошибка, но не могу понять как сделать чтобы не найдено не выводилось. И вот мне нужно, чтобы Не найдено не выводилось, а выводилось только найденное
#include "stdafx.h" #include #include #include
using namespace std;
struct busabroad{ char punkt[10]; int num; char mar[10]; int price; };
int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL,"rus"); SetConsoleCP(1251); SetConsoleOutputCP(1251); int n1=1, i, m; busabroad spisok[5]; cout << "Введите данные" << endl; for(int i=0;i<5;i++){ cout << n1++<<" форма"<< endl; int cp=GetConsoleCP(); SetConsoleCP(1251); SetConsoleOutputCP(1251); cout <<"Введите пункт назначения: "; cin>>spisok[i].punkt; SetConsoleCP(cp); int cp1=GetConsoleCP(); SetConsoleCP(1251); SetConsoleOutputCP(1251); cout <<"Введите номер маршрута: "; cin>>spisok[i].num; SetConsoleCP(cp1); int cp2 = GetConsoleCP(); SetConsoleCP(1251); SetConsoleOutputCP(1251); cout <<"Введите марку автобуса: "; cin>>spisok[i].mar; SetConsoleCP(cp2); int cp3=GetConsoleCP(); SetConsoleCP(1251); SetConsoleOutputCP(1251); cout <<"Введите стоимость проезда: "; cin>>spisok[i].price; SetConsoleCP(cp3); } cout <<"Список: "<< endl;
busabroad sch; for(int i=0;i<5;i++){ for(int j=i+1;j<6;j++) if(strcmp(spisok[i].punkt, spisok[j].punkt)>0) { sch=spisok[i]; spisok[i]=spisok[j]; spisok[i]=sch;}} for(i=0;i<5;i++) { cout<<"Введите пункт назначения: "<>key; SetConsoleCP(cp); for(i=0; i<5; i++){ if(strcmp(key, spisok[i].mar)==0){ cout<<"Введите пункт назначения: "< system("pause"); return 0; }


Ответ

Оформлю в виде ответа то что написал в комментарии. Нужно просто вынести вывод "не найдено" за цикл. Сейчас логика такая что на каждой итерации сравнивается строковый ключ и при равенстве выводятся значения, при неравенстве выводится "не найдено", а нужно выводить "не найдено" только один раз и только если не было ни одного совпадения ключа. Чтобы достигнуть правильного нужно создать переменную например found которая будет следить было ли найдено что-то в цикле и после цикла если found == false то вывести "не найдено".
Вот пример кода, как нужно обрабатывать найденность/ненайденность в цикле, можно запустить онлайн
#include using namespace std;
int main() { bool found = false; for (int i = 0; i < 10; ++i) { if (i == 5) { cout << i << endl; found = true; } } if (!found) { cout << "Not found!" << endl; } return 0; }

Множественный выбор чеков

Есть меню и там группа с чекбоксами.Могу пометить один потом меню исчезает .Как сделать ччтоб мог отметить флажком более одного чека



Ответ

Все дело в том, что в меню не может быть только одна группа с чекбл, он считает ее главной и не слушает команду android:checkableBehavior="all", а автоматом ставит android:checkableBehavior="single"

НАГЛЯДНЫЙ ПРИМЕР
красным выделены группы с порядком
I - android:checkableBehavior="single" II - android:checkableBehavior="all"




//добавь что-нить для теста










Постоянно возвращается http_response_code(200). Recaptcha, Ajax, PHP

Делаю обработку рекапчи средствами PHP, AJAX. Независимо от условий, возвращается код 200. Хотя условие с ошибкой, которое должно вернуть код 400 срабатывает. В связи с этим не работает корректная проверка формы. Пробовал дебажить, работает корректно, заходит в те места, в которые нужно, но по итогу все равно 200. Звонил в поддержку хостинга, думал нужно устанавливать какие-то PHP модули. PHP особо не знаю, впервые столкнулся в таком режиме. Отправка данных происходит только при выполненных условиях (заполнены все поля и капча чекнута, почему возвращается 200 - понять не могу)
HTML











AJAX:

PHP
if ($_SERVER["REQUEST_METHOD"] == "POST") {
var_dump($_REQUEST);
$name = trim($_POST["Name"]); $email = trim($_POST["E-mail"]); $phone = trim($_POST["Phone"]);
$captcha = '';
if (isset($_POST['g-recaptcha-response'])) { $captcha = $_POST['g-recaptcha-response']; }
$captcha = isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : "";
if (empty ($captcha) ) {
echo "check captcha"; http_response_code(400); exit;
} $recipient = "vladknure@gmail.com"; $subject = "Пользователь c Biotech.org.ua.";
$email_content = "Name: $name E-mail: $email Phone: $phone";
$email_headers = "From: website";
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=6LdxczcUAAAAAMeDD8JwV8JkjAGKDhghdyjGK2vK&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']); $decoded_response = json_decode($response); if ($decoded_response->success) { if (mail($recipient, $subject, $email_content, $email_headers)) { http_response_code(200); echo "all is okay"; } else { http_response_code(500); echo "you are spammer"; } } }
jQuery, recaptcha api - все подключено, сюда просто не копировал. Возвращается постоянно "success", то есть попадает только в done. Прикрепляю скриншоты


Ответ

При помощи Visman проблема была решена:
необходимо вместо http_response_code() вызывать header('HTTP/1.0 200 OK'); или header('HTTP/1.0 400 Bad Request'); или header('HTTP/1.0 500 Internal Server Error'); в таком случае будет возвращаться то, что нужно

Android Studio App

Всем привет. Написал я в общем программу(простенький мессенджер). Запустил на эмуляторе все норм, работает(версия на эмуляторе 7.1.1). Решил я про тестить на своем андроиде(версия андроида 6.0.1) ничего не работает, вылетает программа и пишет Unfortunately app has stopped. Заходил я такое на андроид монитор смотрел ошибки, все чисто никаких ошибок. Пытался я менять sdk версию в build.gradle но это не помогает все тоже самое. Устанавливал я apk-debug на свой андроид для тестирования. Как мне это исправить? За ранее спасибо.
Вот мой build.gradle:
apply plugin: 'com.android.application'
android { compileSdkVersion 26 buildToolsVersion '26.0.2' defaultConfig { applicationId "com.example.lado.chatapp" minSdkVersion 21 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets{ main{ jniLibs.srcDirs = ['libs'] } } packagingOptions { exclude 'META-INF/DEPENDENCIES.txt' exclude 'META-INF/LICENSE.txt' exclude 'META-INF/NOTICE.txt' exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/notice.txt' exclude 'META-INF/license.txt' exclude 'META-INF/dependencies.txt' exclude 'META-INF/LGPL2.1' } }
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.google.firebase:firebase-messaging:10.0.1' compile 'com.android.volley:volley:1.0.0' compile 'com.google.firebase:firebase-database:10.0.1' compile 'com.google.firebase:firebase-auth:10.0.1' compile 'com.firebase:firebase-client-android:2.5.2' compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.github.liuguangqiang.swipeback:library:1.0.2@aar' testCompile 'junit:junit:4.12' }
apply plugin: 'com.google.gms.google-services'


Ответ

Все заработало. Что бы такой проблемы не было нужно зайти File -> Settings -> Build,Execution,Deployment ->Instant Run -> uncheck "Enable instant run". Просто отключить Instant Run.

Gitlab / You have not accepted the license agreements of the following SDK component

При сборке проекта по автоматическому файлу .gitlab-ci.yml для android.
You have not accepted the license agreements of the following SDK components: [ConstraintLayout for Android 1.0.2, Solver for ConstraintLayout 1.0.2]. Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager. .gitlab-ci.yml
# This file is a template, and might need editing before it works on your project. # Read more about this script on this blog post https://about.gitlab.com/2016/11/30/setting-up-gitlab-ci-for-android-projects/, by Greyson Parrelli image: openjdk:8-jdk
variables: ANDROID_COMPILE_SDK: "26" ANDROID_BUILD_TOOLS: "26.0.1" ANDROID_SDK_TOOLS: "24.4.1"
before_script: - apt-get --quiet update --yes - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1 - wget --quiet --output-document=android-sdk.tgz https://dl.google.com/android/android-sdk_r${ANDROID_SDK_TOOLS}-linux.tgz - tar --extract --gzip --file=android-sdk.tgz - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter android-${ANDROID_COMPILE_SDK} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter platform-tools - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter build-tools-${ANDROID_BUILD_TOOLS} - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-android-m2repository - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-google_play_services - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter extra-google-m2repository - export ANDROID_HOME=$PWD/android-sdk-linux - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/ - chmod +x ./gradlew
stages: - build - test
build: stage: build script: - ./gradlew assembleDebug artifacts: paths: - app/build/outputs/
unitTests: stage: test script: - ./gradlew test
functionalTests: stage: test script: - wget --quiet --output-document=android-wait-for-emulator https://raw.githubusercontent.com/travis-ci/travis-cookbooks/0f497eb71291b52a703143c5cd63a217c8766dc9/community-cookbooks/android-sdk/files/default/android-wait-for-emulator - chmod +x android-wait-for-emulator - echo y | android-sdk-linux/tools/android --silent update sdk --no-ui --all --filter sys-img-x86-google_apis-${ANDROID_COMPILE_SDK} - echo no | android-sdk-linux/tools/android create avd -n test -t android-${ANDROID_COMPILE_SDK} --abi google_apis/x86 - android-sdk-linux/tools/emulator64-x86 -avd test -no-window -no-audio & - ./android-wait-for-emulator - adb shell input keyevent 82 - ./gradlew cAT


Ответ

На данный момент Google рекомендует такой способ:
запускаете на обычной машине с установленным Android SDK в папке проекта ./gradlew build содержимое $ANDROID_HOME/lisenses помещаете в соответствующую папку на билд-машине (у меня там android-sdk-license и android-sdk-preview-license)
В вашем случае можно положить эти файлы в репозиторий (например, в папку sdk-licenses) и добавить mkdir -p $ANDROID_HOME/licenses/ && cp sdk-licenses/* $ANDROID_HOME/licenses/ в before_script
UPDATE: в репозитории не должно быть файла local.properties, потому что параметр sdk.dir в нем имеет приоритет над $ANDROID_HOME для Gradle.

Как сделать подвижные окна

Как сделать подвижные окна как в этом видео https://www.youtube.com/watch?v=eSPknTG4rxg


Ответ

Почитать тут: статья Draggable
$( function() { $( "#draggable" ).draggable(); } ); #draggable:active { cursor: -webkit-grabbing; } #draggable { width: 150px; height: 150px; padding: 0.5em; cursor: -webkit-grab; } jQuery UI Draggable - Default functionality

Меня можно перенести! Возьми меня!


Не работает слайдер JavaScript

Всем привет, вообщем практикуюсь на JavaScript, дело дошло до слайдера, и тут заминка. Делаю вот такой вот контейнер:

google.com google.com google.com google.com google.com google.com

Применяю следующее css правило:
.img_box > img { opacity: 0; }
Делаю класс c opacity:1 для первого потомка img, далее через js через итерацию и newclass меняю класс у последующих элементов.
Собственно вопрос, почему приоритет для
.img_box > img { opacity : 0; }
Выше чем класс
.opas { opacity: 1; }
И при переборе классов, opacity остается неизменным.
P.S решил проблему задав свойство опасисти, через класс
.slider img { opacity: 1; }
Вообщем, спасибо за ответы, извините если вопрос нубовский. Только учюсь. Успехов Вам!)


Ответ

Ваш вопрос мало касается js Но в целом: вся штука в том, что селектор .img_box > img более спецефичен, чем просто селектор по классу, из-за этого стили не применяются. Аналогичный эффект вы можете получить, если сделаете так:
.img_box img { opacity : 0; }
И перебивать его с помощью такого селектора:
.img_box .opas { opacity : 1; }
Так должно сработать как вы хотите
UPD Про специфичность селекторов, да и в целом неплохая теория по html, css есть на Этом ресурсе Конкретно про специфичность селекторов и их вес: Хабра Документация

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

Реализовываю нижнее меню с треми иконками и, чтобы не копипастить код в 3 активити, реализовал фрагмент, но проблема в том, чтобы узнать, не нажал ли пользователь на уже открытое активити. То есть мне нужно что-то типо "getActivity != OpenedActivity". Как это реализовать ?


Ответ

Для реализации нижнего меню используйте BottomNavigationView
У BottomNavigationView есть два слушателя:
BottomNavigationView.OnNavigationItemReselectedListener BottomNavigationView.OnNavigationItemSelectedListener
В случае, если вы выберите уже выбранный элемент нижнего меню, сработает первый срушатель, иначе второй слушатель.