Страницы

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

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

как удалить ветку в git если в имя попал слэш

случайно набрал в консоле не так и теперь не могу удалить неправильно названную ветку:
git branch develop * master origin/admin-news
как мне удалить последнюю ветку (origin/admin-news)


Ответ

той же командой branch, но с опцией -d
создаём:
$ git branch origin/admin-news $ git branch * master origin/admin-news
и удаляем:
$ git branch -d origin/admin-news Deleted branch origin/admin-news (was 1ba85e8). $ git branch * master

если в ответ на команду git branch -d ... вы получите сообщение вида:
error: The branch 'origin/admin-news' is not fully merged. If you are sure you want to delete it, run 'git branch -D origin/admin-news'.
и вы уверены, что уникальные коммиты в удаляемой ветке вам точно не нужны, то замените, как и предлагается в сообщении, опцию -d на -D
$ git branch -D origin/admin-news Deleted branch origin/admin-news (was a6f907d).

Неадекватное поведение BottomSheet

При инициализации BottomSheet оно частично отображается снизу экрана, далее при попытке подтащить его к верху, что бы оно полностью отобразилось, оно соскальзывает и исчезает. Как это исправить? Или как сделать, что бы появлялся сразу весь BottomSheet на экране?
Видео, как это выглядит: https://www.youtube.com/watch?v=58bhlc-KfYA&feature=youtu.be
код Активити:
public class FirstscreenActivity extends AppCompatActivity implements RecyclerItemClickListener.OnItemClickListener, ItemAdapter.ItemListener {
private BottomSheetDialog mBottomSheetDialog; BottomSheetBehavior behavior; private ItemAdapter mAdapterItem; private FloatingActionButton floatButton;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.front);
mList = (RecyclerView) findViewById(R.id.list); mList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(getApplicationContext()); mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mList.addOnItemTouchListener(new RecyclerItemClickListener(this, this));
mList.setLayoutManager(mLayoutManager);
floatButton = (FloatingActionButton) findViewById(R.id.float_button); floatButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showBottomSheetDialog(); } });
View bottomSheet = findViewById(R.id.bottom_sheet; behavior = BottomSheetBehavior.from(bottomSheet); behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { // React to state change }
@Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { // React to dragging events } }); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapterItem = new ItemAdapter(createItems(), this); recyclerView.setAdapter(mAdapterItem);
}
@Override protected void onResume() { super.onResume(); RecyclerViewAdapter adapter = (RecyclerViewAdapter) mList.getAdapter(); adapter.notifyDataSetChanged(); }
private void showBottomSheetDialog() { if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); }
mBottomSheetDialog = new BottomSheetDialog(this); View view = getLayoutInflater().inflate(R.layout.sheet, null); RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(new ItemAdapter(createItems(), new ItemAdapter.ItemListener() { @Override public void onItemClick(Item item) { if (mBottomSheetDialog != null) { mBottomSheetDialog.dismiss(); } } }));
mBottomSheetDialog.setContentView(view); mBottomSheetDialog.show(); mBottomSheetDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { mBottomSheetDialog = null; } }); }
@Override protected void onDestroy() { super.onDestroy(); mAdapterItem.setListener(null); }
public List createItems() { ArrayList items = new ArrayList<>(); items.add(new Item(R.drawable.camera, "from new shoots")); items.add(new Item(R.drawable.folder_multiple_image, "from ready images")); return items; }
@Override public void onItemClick(Item item) { behavior.setState(BottomSheetBehavior.STATE_COLLAPSED); } }
Адаптер RecyclerView для BottomSheet:
public class ItemAdapter extends RecyclerView.Adapter {
private List mItems; private ItemListener mListener;
public ItemAdapter(List items, ItemListener listener) { mItems = items; mListener = listener; }
public void setListener(ItemListener listener) { mListener = listener; }
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.adapter, parent, false)); }
@Override public void onBindViewHolder(ViewHolder holder, int position) { holder.setData(mItems.get(position)); }
@Override public int getItemCount() { return mItems.size(); }
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageView; public TextView textView; public Item item;
public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); imageView = (ImageView) itemView.findViewById(R.id.imageView); textView = (TextView) itemView.findViewById(R.id.textView); }
public void setData(Item item) { this.item = item; imageView.setImageResource(item.getDrawableResource()); textView.setText(item.getTitle()); }
@Override public void onClick(View v) { if (mListener != null) { mListener.onItemClick(item); } } }
public interface ItemListener { void onItemClick(Item item); } }
xml активити:









xml RecyclerView Item:




Ответ

Хм, вопрос хороший!
Попробуйте указать следующее:
mBottomSheetDialog.getWindow().setGravity(Gravity.BOTTOM);

Область видимости функций

Помогите разобраться с областью видимости. Как мне увидеть функцию ajaxDelete из второго файла?
backend.js (общий)
$(document).ready(function() { function ajaxDelete() { } });
pages.js
$(document).ready(function() { $('.delete-entity').click(ajaxDelete); });


Ответ


pages.js
$(document).ready(function() { $('.delete-entity').click(function() { ajaxDelete(); }); });
backend.js (общий)
$(document).ready(function() { ajaxDelete = function() { alert('qeqqe'); } });

Вывод массива байтов в терминале COM порта

Здравствуйте,
пишу программу на си. Хочу по uart передать следующую последовательность байтов: "0x1F 0x10 0x00 0x01 0x00 0x01" . Т.к. типа byte в си нет, использую char.
Программа выглядит примерно следующим образом:
char str[6]= {31, 16, 0, 1, 0, 1 };
printf("%s
", str);
Проблема в том что эту последовательность я вывожу на терминал последовательного порта и он выводит только 0x1F 0x10, потому что '0' является символом конца строки, поэтому он думает что строка заканчивается и обрезает остальную часть.
Подскажите пожалуйста можно ли вывести на терминал всю строку с нулем вместе, т.е. чтобы ноль не являлся концом строки ?
Использую терминал termite.
Спасибо всем за ответы.
Проблема решена с использованием не массива символов типа char а массива с типом uint8_t (аналог byte в си), которая находиться в библиотеке stdint.h . Код программы:
#include
uint8_t str[6] = {0x1F, 0x10, 0x00, 0x01, 0x00, 0x01}; fwrite(str,sizeof(str),1,stdout);
Спасибо большое, gbg, за помощь.


Ответ

Первое. Тип байтов в C есть и называется uint8_t. Живет в stdint.h
Второе. Используйте fwrite(str,sizeof(str),1,stdout);

Как создать EmailAdressAttribute только для почты Gmail

Для валидации контрола на ввод email использую EmailAdressAttribute. Можно как-то указать чтобы допустимым доменом был только gmail.com?


Ответ

Можно подсмотреть реализацию EmailAddressAttribute на Reference Source и создать свой атрибут для валидации, немного подправив регулярное выражение:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] public sealed class GmailAddressAttribute : DataTypeAttribute { private static Regex _regex = new Regex(@"^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@gmail\.com$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
public GmailAddressAttribute() : base(DataType.EmailAddress) { ErrorMessage = "The {0} field is not a valid e-mail address."; }
public override bool IsValid(object value) { if (value == null) { return true; }
string valueAsString = value as string; return valueAsString != null && _regex.Match(valueAsString).Length > 0; } }

Транслит в MySQL

При переносе сайта с одного хостинга на другой перестала работать функция транслита, на старом работает, на новом нет. Помогите пожалуйста понять в чем проблема. Запрос в phpmyadmin: SELECT translit_func('русский в траслит') Результат:aaaaaaa-a-aaaaaaa
DELIMITER $$ CREATE FUNCTION `translit_func`(`_txt` VARCHAR(250)) RETURNS text CHARSET utf8 BEGIN DECLARE _f varchar(5); DECLARE _t varchar(15); DECLARE done INT DEFAULT FALSE; DECLARE cur CURSOR FOR SELECT f,t from translit; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; open cur; the_loop: LOOP
#get the values of each column into our variables FETCH cur INTO _f,_t; IF done THEN LEAVE the_loop; END IF; set _txt=replace(_txt,_f,_t); END LOOP the_loop;
CLOSE cur; return _txt; END $$ DELIMITER ;
Таблица translit
CREATE TABLE IF NOT EXISTS `translit` ( `t` varchar(3) NOT NULL, `f` varchar(15) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `translit` (`t`, `f`) VALUES ('a', 'а'), ('b', 'б'), ('v', 'в'), ('g', 'г'), ('d', 'д'), ('e', 'е'), ('e', 'ё'), ('zh', 'ж'), ('z', 'з'), ('i', 'и'), ('y', 'й'), ('k', 'к'), ('l', 'л'), ... и т.д.


Ответ

Надо было поменять настройки базы, которые по умолчанию были не те что надо
character_set_database latin1 --> utf8 collation_database latin1_swedish_ci --> utf8_general_ci

Как заменить символы в строке

Необходимо написать программу которая заменяет измененные слова. Например, есть строка "Ты ду_Р-ак или нет?" в данной строке необходимо заменить подстроку ду_Р-ак на ***. Как написать регулярное выражение если пользователь будет пытаться схитрить и писать слово "дурак" через тире, нижний пробел или другие символы, или если часть слова будет написана на латинице а часть на кириллице.
public static void main(String[] args) { String string = "Ты ду_рак или Дур_ак чудак?";
String lower = string.toLowerCase();
String pattern = "дурак"; String p ="***";
String newString = lower.replaceAll(pattern, p); System.out.println(newString); }


Ответ

Предлагаю
[дd][\W_]?[уy][\W_]?[рpr][\W_]?[аa][\W_]?[кk]
См. демо регулярного выражения (необходимо использовать модификатор CASE_INSENSITIVE и UNICODE_CHARACTER_CLASS).
Пояснение
[дd] - д или d [\W_]? - необязательный (? находит 1 или 0 совпадений) символ, отличный от букв и цифр [уy] - р, p или r [\W_]? - необязательный символ, отличный от букв и цифр [рpr] - р, p или r [\W_]? - необязательный символ, отличный от букв и цифр [аa] - а или a [\W_]? - необязательный символ, отличный от букв и цифр [кk] - к или k
Если "лишних" символов может быть больше одного, замените ? на * в [\W_]?, а если нужно исключить пробел, можно использовать [\W_&&[^\s]]? (не забудьте о двойных обратных слешах в Java).
См. демо на IDEONE
String string = "Ты ду_рак или Дур_ак чудак?"; String pattern = "(?iU)[дd][\\W_]?[уy][\\W_]?[рpr][\\W_]?[аa][\\W_]?[кk]"; String p ="***"; String newString = string.replaceAll(pattern, p); System.out.println(newString);

Игра snake на JavaFx

Доброго времени суток, как можно поменять направление змейки так чтобы он не шел в обратную сторону сразу <-->.
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Button; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.StackPane; import javafx.scene.paint.Paint; import javafx.stage.Stage;
public class CanvasEx extends Application { final int size=500, dot_size=10, up=1, right=2, down=3, left=4; int delay=50, length=3, dir=2, food_x, food_y; Canvas canvas; GraphicsContext gc; int x[]=new int[size*size]; int y[]=new int[size*size]; Thread game; boolean lost=false; @Override public void start(Stage primaryStage) {
StackPane root = new StackPane(); canvas=new Canvas(size,size); gc=canvas.getGraphicsContext2D(); canvas.setFocusTraversable(true); root.getChildren().add(canvas); startGame(); canvas.setOnKeyPressed(new EventHandler(){ @Override public void handle(KeyEvent e) { KeyCode key=e.getCode(); if(key.equals(KeyCode.UP)) dir=up; if(key.equals(KeyCode.DOWN)) dir=down; if(key.equals(KeyCode.LEFT)) dir=left; if(key.equals(KeyCode.RIGHT)) dir=right; }
}); Scene scene = new Scene(root, size, size);
primaryStage.setTitle("Hello World!"); primaryStage.setScene(scene); primaryStage.show(); } private void draw(GraphicsContext gc){ gc.clearRect(0, 0, size, size); if(!lost){ gc.setFill(Paint.valueOf("green")); gc.fillOval(food_x, food_y, dot_size, dot_size); gc.setFill(Paint.valueOf("red")); gc.fillOval(x[0], y[0], dot_size, dot_size); gc.setFill(Paint.valueOf("orange")); for(int i=1; i }else{ gc.setFill(Paint.valueOf("black")); gc.fillText("Game Over", size/2-50, size/2-15); game.stop(); } } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); }
private void startGame() { length=3; for(int i=0; i
}); game.start(); }
private void locateFood() { food_x=(int)(Math.random()*((size/dot_size)-1))*dot_size; food_y=(int)(Math.random()*((size/dot_size)-1))*dot_size; } private void checkFood() { if(x[0]==food_x && y[0]==food_y){ length++; locateFood(); } } private void checkCollision() { if(x[0]>=size) lost=true; if(y[0]>=size) lost=true; if(x[0]<0) lost=true; if(y[0]<0) lost=true; for(int i=3; i0;i--){ x[i]=x[i-1]; y[i]=y[i-1]; } if(dir==up)y[0]-=dot_size; if(dir==down)y[0]+=dot_size; if(dir==right)x[0]+=dot_size; if(dir==left)x[0]-=dot_size; } }


Ответ

Мне кажется тут решение в лоб:
if(key.equals(KeyCode.UP)) dir=up; if(key.equals(KeyCode.DOWN)) dir=down; if(key.equals(KeyCode.LEFT)) dir=left; if(key.equals(KeyCode.RIGHT)) dir=right;
В этом участке кода просто добавляем проверки на dir != down (в случае, если KeyCode.UP) и так далее.

Откат изменений в базе данных после Exeptions

Разрабатываем командный проект на Python с использованием Django. Хранение кода и поддержка версионности через gitlab. При push нового кода, идет заливка на сервер. Структура базы данных меняется за счет migrate в Django. Как быть с данными в БД? Например, идут изменения: столбик удалился, залились новые записи, удалились записи (строки). В какой-то момент вылетел Exeption. Структуру можно откатить через все те же migrations, a как откатить изменения данных?? (чтобы вернуть сервер в предыдущее рабочее состояние) Размеры базы десятки терабайт, по этой причине "до изменений сделать резервную копию, и, если слетело, подставить копию" не вариант. Какие есть идеи или отработанные подходы, стандартные сервисы?


Ответ

Иначе подходите к проектированию изменений БД. Разносите по времени изменение кода и БД. Сначала меняйте код так, чтобы он работал одновременно на текущей и на новой схемах БД. Протестируйте этот код и выкатывайте в продакшн. Если какие-то ошибки произойдут на этом этапе, просто откатите код. Когда Вы убедитесь, что новый код работает и ошибок нет, выкатывайте новую схему БД.

Qt 5 - QSettings, не пишется ini-файл

Приветствую. Есть код: сериализация настроек приложения, сделанных как QProperty, в ini файл(потому что мне сказали, что реестр - плохой стиль).
Settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, QApplication::organizationName(), QApplication::applicationName());
QString path = Settings->fileName();
и чуть позже:
const QMetaObject *metaobject = metaObject(); int count = metaobject->propertyCount(); for (int i = 0; iproperty(i); const char *name = metaproperty.name(); QVariant value = property(name);
QString Key = QString(name);
Settings->setValue(Key, value); }
В переменной path путь к ini-файлу:
path = C:/Users/ILIA/AppData/Roaming/HighwaySoftware/Vesta 2016.ini
От русских букв в путях я ушел давно. Файл не создаётся. Думал, нет прав на запись, запустил из-под Visual Studio 2013, запущенной от администратора - нет результата. Чтобы вы не думали, что файл я не нашёл, я его искал через Everything c запросом:
*vesta*.ini
где vesta - имя приложения, его нет. В чём дело? В реестр вся информация пишется(правда, не всегда, я это не поборол).


Ответ

Данные сохраняются при вызове метода sync, а также при вызове деструктора и по интервалу в event loop. Вы создаёте QSettings в куче и, вероятно, сразу завершаете приложение, не удаляя объект.
Дебаггер останавливает все потоки, поэтому если вы после записи настроек замораживаете приложение, то настройки не успевают сохраниться.

resolv.conf сбрасывается после каждой перезагрузки сервера

После каждой перезагрузки сервера приходится вручную менять файл resolv.conf (туда записывается ip моего сервера, а не то что нужно) командой
echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf
Можно ли как-то избежать этого? Не понимаю, почему он сбрасывается. А когда там записано не 8.8.8.8, то curl, websocket перестаёт работать.
Сервер под ubuntu 14.04
Содержимое /etc/network/interfaces
auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 141.8.196.103 gateway 141.8.196.1 netmask 255.255.255.0 network 141.8.196.0 broadcast 141.8.196.255 dns-nameservers 141.8.192.2
auto eth0 iface eth0 inet dhcp dns-search google.com dns-nameservers dnsserverip
Содержимое /etc/resolv.conf
nameserver 141.8.192.2


Ответ

у вас в файле /etc/network/interfaces записаны конфликтующие настройки.
уточните у администратора вашей сети, как на вашем компьютере должна быть сконфигурирована сеть: динамически или статически. если динамически, тогда закомментируйте первую секцию, начинающуюся с:
iface eth0 inet static
если статически — вторую, начинающуюся с:
iface eth0 inet dhcp
а заодно уточните и ip-адрес dns-сервера(-ов). ведь тот, что сейчас используется, видимо, уже нерабочий и подлежит замене. как несложно догадаться, он(-и) может(-гут) быть указан(-ы) директивой dns-nameservers (если будет несколько, то через пробел).
если администратор ничего нового по поводу dns-сервера(-ов) не расскажет, то укажите там, например, google-вские публичные серверы:
dns-nameservers 8.8.8.8 8.8.4.4

доп. информация: https://wiki.debian.org/ru/NetworkConfiguration

Оптимизация SELECT со статистикой

Есть такой запрос:
SELECT COUNT(`count`) AS 'visits', `code` FROM `om_log` WHERE `code` <> '0' AND `date` >='1464728400' AND `date` <='1467320399' GROUP BY `code` ORDER BY `code`;
В таблице записей очень много, это статистика посещения сайта. Обычно она собирается за месяц. Есть идеи как оптимизировать данный запрос, не прибегая к рефакторингу и использованию промежуточных таблиц с счетчиками?
EXPLAIN:
id | select_type | type | possible_keys | key | key_len | ref | rows | Extra 1 | SIMPLE | range | "code,date" | date | 5 | NULL | 1420 | "Using where; Using temporary; Using filesort"


Ответ

Данную оптимизацию может зделать MySQL вместо меня с помощью механизма партиционирования. Это физическое разделение файла таблицы на несколько по определенному признаку. Таким образом запросы начинают выполнятся в разы быстрее. Главное не переусердствовать с их количеством.
ALTER TABLE `om_log` PARTITION BY RANGE(date) PARTITIONS 6( PARTITION less2015 VALUES LESS THAN (UNIX_TIMESTAMP('2015-01-01')), PARTITION less2016 VALUES LESS THAN (UNIX_TIMESTAMP('2016-01-01')), PARTITION less2017 VALUES LESS THAN (UNIX_TIMESTAMP('2017-01-01')), PARTITION less2018 VALUES LESS THAN (UNIX_TIMESTAMP('2018-01-01')), PARTITION less2019 VALUES LESS THAN (UNIX_TIMESTAMP('2019-01-01')), PARTITION other VALUES LESS THAN (MAXVALUE) );
Сейчас я сделал их с запасом, но похорошому не плохо добавлять партиции кроном при необходимости, например в конце года, а партицию 5летней давности допустим удалять.
Сделать партиционирование существующей таблицы, которая активно используется невозможно, возникает блокировка таблицы и это ложит сайт. Необходимо создавать новую таблицу, на которую переключать работу сайта, а после переносить небольшими порциями все записи туда.
Сейчас решена задача добавлениям комбинированных индексов! Скорость запросов 2-5 сек. Это более менее приемлемое время вместо бывших 90сек.

Зависает screen после переключения на другое окно, либо после разблокировки экрана

Терминал. В нём запущена сессия screen по ssh. Всё работает хорошо. Однако после того, как переключиться на другое окно в системе (Debian 8), а затем вернуться через какое-то время, то screen перестаёт реагировать на клавиатуру и мышь. Соответственно такая же ситуация происходит после разблокировки экрана.
С чем это может быть связано и как это можно починить?


Ответ

Прозреваю, что из-за неактивности отваливается ssh.
Проверить просто
Запустить какой-нибудь ping 127.0.0.1 и уйти в другое окно. Если по возвращению пинг будет бежать - это точно отвал по неактивности.
Как лечить
Накрутить в sshd_config вот эту парочку:
TCPKeepAlive yes ClientAliveInterval 60
Время задается в секундах. Первый просто заставит ssh слать тестовые пакеты-пинги, второй задает частоту.

Битовый сдвиг влево

Почему переменная val будет инициализирована значение 1, а не значением 0?
int val = 1 << 32;


Ответ

Согласно документации (JLS 15.19):
If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.
то есть
Если тип левой части после numeric promotion — int [это как раз наш случай], то лишь пять младших бит из правой части будут использованы в качестве размера сдвига. Эффект такой же, как если бы правую часть подвергли операции & с маской 0x1f (0b11111). Таким образом, расстояние сдвига всегда находится в промежутке от 0 до 31, включительно.
Это означает, что сдвиг на 32 бита работает как сдвиг на 0, на 33 как на 1 и т. д.

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

Всем привет! Кто может подсказать как в обработчике ошибок получить ссылку из за которой возникло исключение. К примере есть ссылка: site.ru/a/b/c - которая является не рабочей (будет выброшено NotFoundException) Есть обработчик ошиок actionError():
public function actionError() { //Как вот здесь получить site.ru/a/b/c }
Пробовал использовать $app->request->referrer, но это свойство возвращает последнюю удачно загруженную страницу.


Ответ

Ура нашел!
Yii::$app->request->url
Я почему то решил что в свойстве Yii::$app->request->url будет находится ссылка на обработчик ошибок.

Oracle count по условию

Всем доброго времени суток! Столкнулся с такой проблемой, есть запрос который возвращает
| SOT | KUT | K1 | K2 | YADRO | GR | |------|------|----|----|-------|-----| | 2055 | 1,31 | 0 | 3 | 2 | 101 | | 2055 | 1,31 | 0 | 3 | 2 | 101 | | 2055 | 1,31 | 0 | 3 | 2 | 103 | | 2055 | 1,31 | 1 | 0 | 1 | 100 | | 2055 | 1,31 | 0 | 3 | 3 | 102 | | 2055 | 1,31 | 0 | 3 | 3 | 102 |
Где столбцы K1 и K2 расчётные, K1 показывает сколько различных групп(GR) принадлежащих ядру(YADRO) 1 посещает сотрудник (SOT), K2 показывает сколько различных групп(GR) НЕ принадлежащих ядру(YADRO) 1 посещает сотрудник (SOT). Ядра содержат только уникальные группы, в двух разных ядрах группы не повторяются. Запрос
select sot, round(sum(time)over(partition by sot)/25920,2) as Кутил, case when yadro=2 then count(distinct gr)over(partition by sot,case when yadro=2 then 0 else 1 end) else 0 end as K1, case when yadro!=2 then count(distinct gr)over(partition by sot,case when yadro!=2 then 0 else 1 end) else 0 end as K2,
... from ...
Проблема в том что запрос возвращает значения с нулями а нужно чтобы было как то так
| SOT | KUT | K1 | K2 | YADRO | GR | |------ |------ |---- |---- |------- |----- | | 2055 | 1,31 | 1 | 3 | 2 | 101 | | 2055 | 1,31 | 1 | 3 | 2 | 101 | | 2055 | 1,31 | 1 | 3 | 2 | 103 | | 2055 | 1,31 | 1 | 3 | 1 | 100 | | 2055 | 1,31 | 1 | 3 | 3 | 102 | | 2055 | 1,31 | 1 | 3 | 3 | 102 |

Чтобы не было нулей а были общие цифры во всех столбцах, буду очень благодарен за помощь, сразу говорю обёртки предлагать только в крайнем случае, хотелось бы обойтись без лишних подзапросов и т.д.


Ответ

Не уверен , но стоит попробовать вот так :
count(distinct case when yadro=2 then gr else null end )over(partition by sot) as K1

Появление кнопки приложения когда в буфер скопирован текст

Появление кнопки приложения когда в буфер скопирован текст. Можете рассказать что это и если можно как это реализовать. Буду рад даже ссылкам на сторонние ресурсы.


Ответ

Возможно, есть более элегантное решение этой задачи, но если нет времени или лень искать, можно сделать так:
@Override protected void onResume() { super.onResume(); checkClipboard(); }
private void checkClipboard() { ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String pasteData = "";
if (clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) { ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); pasteData = item.getText(); }
if (pasteData.equals("")) showButton(); else hideButton(); }
private void showButton() { // показать кнопку, если она еще не показана } private void hideButton() { // скрыть кнопку, если она на еще не скрыта }

HTML: позволить пользователю менять ширину столбцов в таблице

Добрый день.
Имеется таблица (тэг table), количество записей и столбцов неизвестны. Хотелось бы сделать функционал, который разрешит пользователю самостоятельно менять ширину любого столбца с автоматическим изменением ширины оставшихся, аналогично как это делается в MS Excel или других электронных таблицах (навёл курсор на границу столбца, нажал кнопку мыши, потащил, отпустил - ширина изменилась).
Предположим, что имеется HTML5. Excel не установлен.


Ответ

Table

ТекстТекст
ТекстТекст

Приблизительно так, если на Jquery ui http://jquery.page2page.ru/index.php5/%D0%A0%D0%B0%D1%81%D1%82%D1%8F%D0%B3%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5_%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D1%8B

Создание экземпляра класса, независимого от других объектов

Здравствуйте. Создаю экземпляр по такой схеме:
type TExercise = object;
var TMyExercise: TExercise;
Получается что я могу не объявлять переменные на форме для создания экземпляра класса и обращаться к объекту без ссылок на форму(если бы я создал из нее). Так же это позволяет мне иметь единственный экземпляр, в котором хранятся нужные мне данные, используемые несколькими формами.
Но так создают из-за обратной совместимости, судя по справке.
Есть ли другой способ создавать независимый от других объектов класс в Borland Delphi 7?


Ответ

В Delphi обычно не принято называть переменные с большой буквой T в начале, поскольку такая буква в начале литерала обычно говорит о том, что это тип (от англ. type, например: TExercise, TObject, TStringList и т.д.). Так удобнее читать код, даже свой :)
Обычно класс объявляется, например, так:
TExercise = class(TObject) private FMyInt: Integer; FMyString: string; public property Int: Integer read FMyInt write FMyInt; property Str: string read FMyString; // только для чтения end;
Для того, чтобы создать экземпляр класса, нужно вызвать его конструктор:
MyExercise := TExercise.Create;
Когда работа с объектом окончена и он больше не нужен, обязательно нужно освободить память занимаемую объектом:
MyExercise.Free;
Иначе будут утечки памяти и она рано или поздно закончится.

Для создания "по-быстрому" независимого глобального объекта для использования на разных формах можно сделать так:
unit UnitExercise;
interface
type TExercise = class(TObject) private MyInt: Integer; MyString: string; public property Int: Integer read MyInt write MyInt; property Str: string read MyString; // только для чтения end;
var MyExercise: TExercise;
implementation
initialization MyExercise := TExercise.Create;
finalization MyExercise.Free;
end.
И добавить модуль UnitExercise в список используемых модулей (uses) в те модули, в которых предполагается использование этого объекта.
Однако, в такой конструкции есть недостаток: вы практически не контролируете порядок создания и уничтожения таких объектов (если их много, они в разных модулях и еще зависят друг от друга), что может быть актуально для больших проектов. Управлять порядком вызова секций initialization и finalization можно, меняя порядок объявления модулей в проекте и его модулях, но это очень сложная эквилибристика. Если интересно, то это тема для отдельного вопроса.

Generic Типы и двойной UpCast

всем привет, имеется следующий пример:
public abstract class Shape { } public class Circle : Shape { }
public interface IContainer { T Figure { get; } }
public class Container : IContainer { private T figure;
public Container(T figure) { this.figure = figure; }
public T Figure { get { return figure; } } }
class Program { static void Main() { Circle circle = new Circle();
IContainer container = new Container(circle);
Console.WriteLine(container.Figure.ToString());
// Delay. Console.ReadKey(); } }
меня интересует вот эта строка
IContainer container = new Container(circle);
-экземпляр circle (передаваемый в качестве аргумента конструктора) ни приводится ни к какому типу в данном случае - т.к тип Т (я знаю, что правильно говорить тип места заполнения типом Т, но просто "тип Т" - будет короче) у класса Container мы закрыли тем же типом, что и данный экземпляр (и я имею ввиду, что т.к типы у них одинаковые, то и приводится не к чему.)
Итак, у нас сперва тип Container приводим к типу IContainer, а поле figure типа Circle приводится к типу Shape.
Почему поле figure внутри класса Container приводится к типу Shape?
итак мои предположения:
1) передаваемый в качестве аргумента экземпляр тут ни причем - т.к как уже было сказанно выше сам экземпляр никчему не приводится.
2)Из-за того, что тип Container мы привели к типу IContainer - тип Т у которого мы закрыли типом Shape
и отсюда возникает еще один вопрос: у нас одновременно происходит как бы два UpCast -а : Container - IContainer;
Circle-Shape; - какой из них так скажем влияем на передаваемый аргумент конструктора - наш экземпляр circle (да-да, я знаю, что выше писал, что UpCast -a экземпляра circle не происходит - просто в предыдущем примере экземпляр приводится к типу Shape )
IContainer container = new Container(circle);
но, раз поле figure меняет тип, а ссылка на это поле хранится в этом экземпляре, который мы передаем в качестве аргумента конструктора.
Моя догадка заключается в том, что раз мы тип Т у Container (Circle) - тот тип которого и аргумент конструктора circle - приводим к типу Т у IContainer(Shape), то и этот аргумент конструктора типа Circle также неявно UpCast - ится "следуя" изменениям своего типа - и соответственно затем произойдет UpCast типов внутри этого экземпляра в том числе и поля figure - которое изменит свой тип Circle на Shape.


Ответ

Смотрите.
У вас в строке IContainer container = new Container(circle); есть лишь одно приведение типов: левая часть имеет тип IContainer, а правая — Container
Почему такое приведение возможно? Дело в out, которое у вас в interface IContainer. Смысл этого самого out таков: если Т1 — подтип T2, то IContainer считать подтипом IContainer
Таким образом, у вас Container приводится к IContainer, а вследствие out IContainer приводится к IContainer
То есть при этом реальный тип объекта как был, так и остаётся Container. То, что к этому объекту можно получить доступ по ссылке типа IContainer, не заставляет тип поля самого объекта поменяться.

Почему вообще приведение из IContainer к IContainer возможно? Это контролируется компилятором. Дело в том, что тип T у вас находится в интерфейсе позиции возвращаемого значения. Это значит, что если у вас реально в руках есть IContainer, то он удовлетворяет требованиям на IContainer: его свойство Figure возвращает объект типа Circle, а значит, его можно трактовать как объект типа Shape
(Если бы T находилось в позиции аргумента, а не возвращаемого значения, компилятор не дал бы вам скомпилировать интерфейс с out.)

База записей с избранным

Мне нужно организовать хранение записей в базе с возможностью отмечать их как избранные. Запись выглядит так.
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto" }
Вот способы реализации:


Как лучше поступить?


Ответ

Если в системе предполагается более одного пользователя:) То конечно отдельной таблицей.
Минимальный набор полей:
message_id - ид сообщения, или что у вас в системе помечается? user_id - ид пользователя
Т.е. типичная связь многие-ко-многим. Каждое сообщение может быть помечено избранным несколькими пользователями; один пользователь может пометить несколько сообщений.

Запуск базы данных из терминала Ubuntu

Новичек в базах данных. Уставил MySQL, ввел в терминал mysql -u root -p, далее ввожу пароль. Возникает ошибка:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Содержимое файла my.cnf:
# # The MySQL database server configuration file. # # You can copy this to one of: # - "/etc/mysql/my.cnf" to set global options, # - "~/.my.cnf" to set user-specific options. # # One can use all long options that the program supports. # Run program with --help to get a list of available options and with # --print-defaults to see which it would actually understand and use. # # For explanations see # http://dev.mysql.com/doc/mysql/en/server-system-variables.html
# # * IMPORTANT: Additional settings that can override those from this file! # The files must end with '.cnf', otherwise they'll be ignored. #
!includedir /etc/mysql/conf.d/ !includedir /etc/mysql/mysql.conf.d/


Ответ

Судя по сообщению об ошибке у вас не запущен сервер MySQL, проверьте висит ли в процессах mysqld
ps uax | grep mysqld
Если его нет, попробуйте запустить при помощи команды
sudo service mysql start
При помощи команды service вы можете управлять сервером MySQL, например, останавливать
sudo service mysql stop
или рестартовать
sudo service mysql restart
Если попытка старта сервера не приводит к результатам, он не появляется среди процессов, следует обратиться к логам в /var/log/mysql, возможно там сообщается какая-то дополнительная информация о том, почему сервер не может стартовать.
Проверьте где расположен файл сокета, для этого откройте конфигурационный файл /etc/mysql/my.cnf, найдите секцию [mysqld] и директиву socket. Обычно она указывает на /var/run/mysqld/mysqld.sock. Если у вас путь не совпадает с тем, о котором сообщает утилита mysql, попробуйте указать его явно
mysql -u root -p --socket=/var/run/mysqld/mysqld.sock
UPDATE
Если сокет вообще отключен, тогда взаимодействие осуществляется через сеть, в этом случае в качестве хоста следует указывать IP-адрес 127.0.0.1
mysql -h 127.0.0.1 -u root -p
Есть два способа соединения с MySQL-сервером: через сокет и через сеть. Когда в качестве хоста вы пишите localhost - соединение по умолчанию идет через сокет, когда пишите IP-адрес - через сеть.

Что после компиляции попадает в апк из подключенного движка?

Вот говорят, что если реализация физики в игре простая, то лучше не подключать движок, да бы не захламлять проект. Я например в адроид студио к проекту подключаю движок AndEngine . И например использовал пару классов, выходит при компиляции в апк в итоге попадут все классы библиотеки? Даже те которые я не использовал? Почему студия не может скомпилировать только использованные?


Ответ

По умолчанию - да, все классы из всех зависимостей будут скомпилированы и упакованы в apk файл. Да, некоторые из них могут быть незадействованы вовсе и всё равно попадут в итоговый файл.
Для решения этой проблемы вы можете использовать proguard - он удалит весь неиспользуемый код и ресурсы. Вот ссылка на доки: тык
Вот ещё несколько устаревший, но неплохой пример настройки proguard для андроида: тык