Страницы

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

пятница, 7 февраля 2020 г.

Статистика использования разных разрешений экранов

#android


Подскажите, пожалуйста, где можно найти статистику использования телефонов с разным
разрешением экранов на 2015-2016 год? 
    


Ответы

Ответ 1



Android Dashboards - наиболее очевидное и достоверное место статистики по android-устройствам

что такое неделимая операция семафора?

#cpp


"Неделимая операция - это операция, которая не может быть прервана."  Непонятно это
объяснение. Могли бы вы осветить более развернуто этот момент и если возможно с примером
кода.
    


Ответы

Ответ 1



Два параллельных потока выполнения представляете? Нет никаких гарантий, кто что и когда делает. Вплоть до того, что вы выполняете присваивание типа long long x = f(y); где long long - 8 байт, а запись при этом идет по 4 байта - пишется одно слово, затем второе. Так вот, параллельное выполнение не гарантирует не только что никто не вклинится между вычислением функции и присвоением результата, но что даже такое сохранение будет выполнено без вмешательства другого потока. И если есть Поток 1 Поток 2 x = 0xFFFF0000; x = 0xABCD1234; то в результате может оказаться, что x не равно ни первому значению, ни второму, а, скажем, x == 0xFFFF1234. Специально привел пример понеприятнее. А неделимая операция - во время выполнения которой переключение между потоками гарантированно не произойдет. Так более-менее понятно? Семафор - есть такой std::mutex, и если вы выполнили для него lock(), то пока не будет выполнен unlock(), все прочие операции lock() заставляют поток ожидать. std::mutex m; Поток 1 Поток 2 m.lock(); m.lock(); x = 0xFFFF0000; x = 0xABCD1234; m.unlock(); m.unlock(); Тут вы гарантируете, что как бы причудливо не переплетались эти потоки, но x не примет какого-то непонятного значения, а будет либо 0xFFFF0000, если первым захватил мьютекс второй поток, либо 0xABCD1234 - если первый. Т.е., например, первый поток пришел первым, вызвал lock(). Пришел второй поток, вызвал lock() - и остановился в ожидании, пока мьютекс не будет освобожден. Первый поток выполнил присваивание, вызвал unlock() и пошел дальше. И только теперь вызов lock() вторым потоком завершится, и он сможет выполнять свое присваивание. Примерно так...

Ответ 2



На практике я чаще встречаю синоним: атомарная операция (прямой перевод). Это операция, которая для "сторонних наблюдателей" (других потоков?) гарантированно не может быть "в процессе": она либо уже выполнилась, либо ещё не началась. Неделимая, потому что для наблюдателей снаружи она не может быть разделена на отдельные наблюдаемые шаги. Эти операции важны, когда к некоторому элементу данных обращаются несколько потребителей без синхронизации (никто не говорит им, когда смотреть можно, а когда нет), и каждый потребитель должен видеть этот элемент данных в целостном состоянии. Как семафор должен быть в состояниях закрыт/открыт.

Как укоротить метод? с#

#c_sharp #net #winforms #checkbox


Как можно укоротить этот метод?
В зависимости от входящего значения он отмечает чекбоксы.

private void CheckB(int i)
    {
        switch (i)
        {
            case 0:
                c1.Checked = true;
                return;
            case 1:
                c2.Checked = true;
                return;
            case 2:
                c3.Checked = true;
                return;
            case 3:
                c4.Checked = true;
                return;
            case 4:
                c5.Checked = true;
                return;
            case 5:
                c6.Checked = true;
                return;
            case 6:
                c7.Checked = true;
                return;
            case 7:
                c8.Checked = true;
                return;
            case 8:
                c9.Checked = true;
                return;
            case 9:
                c10.Checked = true;
                return;
            case 10:
                c11.Checked = true;
                return;
            case 11:
                c12.Checked = true;
                return;
        }

    


Ответы

Ответ 1



Можно поместить чекбоксы в массив: private readonly CheckBox[] checkBoxes; В конструкторе (после InitializeComponent();) создаем массив: checkBoxes = new[] { c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12 }; Тогда ваш метод будет выглядеть так: private void CheckB(int i) { if (i >= 0 && i < checkBoxes.Length) checkBoxes[i].Checked = true; }

Ответ 2



Можно сделать через Dictionary. Возможно так быстрее будет. private readonly Dictionary checkBoxes = checkBoxes = new Dictionary(){ {0, c1}, {1, c2}, ..., {11, c12}}; private void CheckB(int i) { CheckBox box; checkBoxes.TryGetValue(i, out box); box.Checked = true; }

Поиск файла с наименьшим количеством слов

#linux


Как найти и вывести на экран имя файла с наименьшим количеством слов в файле?
    


Ответы

Ответ 1



Зайдите из консоли в каталог с файлами и выполните данную команду: ls --file-type | grep -v '/$' | xargs wc -w | sort -g | head -n 1 | awk '{print $2}'

Ответ 2



Открываешь файл, считаешь количество пробелов +1 и запоминаешь где-нибудь эту пару (имя файла-число слов), береш другой файл и делаешь то же самое. Если число слов меньше чем то которое ты запомнил на предыдущем шаге, то заменчешь имя файла и новый минимум и так далее..

Почему отступ считается по разному на разных девайсах?

#java #android #android_layout


Мне нужно поднять активити вверх на 15% от высоты экрана(вне зависимости от того
какой экран, элемент должен подняться на 15%) за пределы видимости экрана... Я делаю
это таким образом 

Вот у меня есть кастомная вьюха




/.../







/.../





вот здесь я устанавливаю параметры, чтоб это сделать

private void initVar() {
//  Margin set in % of the screen
    int marginLeft = 0;

------>   int marginTop = 15; вот здесь я указываю процент от высоты экрана

    int marginRight = 0;
    int marginBottom = 0;

//      Здесь мы получаем высоту и ширину экрана
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    screenWidth = size.x;
    screenHeight = size.y;

//      Здесь мы устанавливаем параметры для нашего вью
    RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    param.setMargins((screenHeight * marginLeft) / 100, -((screenHeight * marginTop)
/ 100),
            (screenHeight * marginRight) / 100, (screenHeight * marginBottom) / 100);

    mTextureView = (AutoFitTextureView) findViewById(R.id.texture);
    mTextureView.setLayoutParams(param);


и вот что получается, когда я загружаю это все дело на телефон Samsung S5 1980x1080
то это выглядит как я и рассчитываю, ровно 15% занято(белая полоса снизу это дефолтный
цвет экрана который открывается когда мы поднимаем вью)



Но когда я тот же проект загружаю на эмулятор 1280x800 то почему то экран поднимается
не на 15% а на 25-30%(точно не на 15%)



А если попробовать на эмуляторе с разрешением 1440*2560, то получается вот так



На первом скриншоте белая полоса  не доходит до надписи "Front picture", а на втором
захватывает его и даже больше а на а на третьем это вообще 50% экрана... 

Очень странно получается потому что формула по которой идет расчет подразумевает,
что я беру высоту экрана и получаю от нее ровно 15%... 

Почему на одном устройстве это 15%, а на другом  это больше а на третьем это вообще
50% экрана??

Что я делаю не так??

Вот скриншот на котором margin установлены на 0 и на экране не должно быть белой
полосы, но она есть, хотя на реальном девайсе ее нет...


    


Ответы

Ответ 1



Вам нужно учитывать плотность экрана. Данные (ширина и высота) дисплея из системы вам выдают в пиксилях и они реальны. Но когда вы указываете в коде дополнительные цифры, их нужно пересчитывать под плотность экрана. К примеру, вы хотите добавить 15 пикселей высоты для вьюшки. Вы берете view.getHeight() и получаете размер в пикселях и когда прибавите просто число view.getHeight() + 15, на экранах с разной плотностью эффект быдет выглядеть по разному, где нормально, где меньше. Но выполнив view.getHeight() + dpToPx(getActivity(), 15). Ваши 15 пикселей пересчитаются в реальные пиксели для вашего экрана. public static int dpToPx(Context context, float dp) { // add 0.5 to round up return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5); } public static int pxToDp(Context context, int px) { // add 0.5 to round up return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5); } UPD Технически у вас расчеты правильны. За исключением того, что вы берете расчет высоту всего экрана. У вас не учитывается высота софтварных кнопок (бек\хом\таск) берите высоту вашего контейнера, а не высоту экрана. Так как высота контейнера известна только после ее создания, вешайте лайоут обсервер (к примеру в onCreate). ViewTreeObserver viewTreeObserver = mViewRoot.getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int viewHeight = mViewRoot.getHeight(); mViewRoot.getViewTreeObserver().removeGlobalOnLayoutListener(this); // тут все ваши расчеты } }); mViewRoot - это Ваш рутовый контейнер. И все равно при расчетах в % у вас будут отличаться цифры, а значит оно не будет выглядеть одинаково на всех устройствах(я правильно понимаю? что кнопка фото у вас статичного размера :)). Я бы рекомендовал выставить в xml нужную высоту в для нижней view (mTextureView) , и изменять в пропорциях размер превью камеры (на остаток высоты) ;)

Ответ 2



Попробуйте вот так высоту/ширину экрана получать: public static int getWidth(AppCompatActivity act) { DisplayMetrics displaymetrics = new DisplayMetrics(); act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); return displaymetrics.widthPixels; } public static int getHeight(AppCompatActivity act) { DisplayMetrics displaymetrics = new DisplayMetrics(); act.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); return displaymetrics.heightPixels; }

Ответ 3



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

Как построить эллипс в консоли?

#java #математика


................
......**........
.....*..*.......
....*....*......
....*....*......
....*....*......
.....*..*.......
......**........
................ 



Что-то вроде такого

А именно не могу понять как использовать формулу x^2/a^2 + y^2/b^2 = 1
    


Ответы

Ответ 1



Формулу использовать так: выражаете одну переменную через другую, получается что-то вроде x = sqrt(a^2*(1-y^2/b^2), где y изменяется от -b до b (обычно выражают наоборот - y через x, но так как "изображение" в консоли строится сверху вниз, то имеет смысл выражать x через y). Эта формула уже позволяет построить правую половину эллипса (x обозначает количество точек перед звездочкой от вертикальной оси симметрии). Чтобы построить левую половину, нужно выразить отступ звездочек от левого края рисунка, например так: a - x. Если нужен отступ от левого края, добавляете еще константу. Строка из звездочек и точек будет составляться примерно так: round(xx)*'.' + '*' + 2*round(x)*'.' + '*' + round(xx)*'.' Это псевдокод (на самом деле "валидный" код на python), умножение обозначает количество повторений символа, сложение - сцепление строк, round - округление к ближайшему целому числу, xx = a - x. С учетом того, что при y = 0 вторая координата тоже равна нулю, и должна рисоваться только одна звездочка, нужно подправить эту "формулу" так: '.'*round(xx) + '*' + (2*round(x)-1)*'.' + int(round(x)>0)*'*' + '.'*round(xx) (int в данном случае приводит булевое значение к целому) Пример того что получится (параметры a = 6, b = 6): ......*...... ...*.....*... ..*.......*.. .*.........*. *...........* *...........* *...........* *...........* *...........* .*.........*. ..*.......*.. ...*.....*... ......*...... Если нужна более "гладкая" кривая (без разрывов в первой и последней строке, например), нужно смотреть в сторону алгоритма Брезенхэма.

Определение региона и оператора связи по номеру телефона

#asterisk #freepbx #телефон


Добрый день!

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

Прошу помочь придумать максимально простой и быстрый алгоритм определения принадлежности
номера к оператору.

Дополнительно замечу, что вариант звонить, затем оценивать сколько денег ушло - не
годится, т.к. пользователь номера может оператора менять достаточно часто (в историческом
масштабе).

Если существует какое-либо API у операторов для решения этой задачи, то будет очень
здорово, если на него укажете.

Реализовывать выбор направлений планируем через Dial-plan системы asterisk.
    


Ответы

Ответ 1



Добрый день! Если существует какое-либо API у операторов для решения этой задачи, то будет очень здорово, если на него укажете. http://mnp.tele2.ru/gateway.php?90000000 http://www.megafon.ru/api/mfn/info?msisdn=90000000

Ответ 2



Нашел решение. Ключевое слово HLR. HLR Lookup это что-то среднее между Whois и ping, но для телефонных номеров. Существует (как оказалось) множество сервисов, которые позволяют производить проверку номера. Единственный минус, что они все платные. Например, https://www.hlr-lookups.com/ https://www.hlrlookup.com/prices и пр.

Отправить сообщение пользователю через VK API из приложения с типом “Веб-сайт”

#vkontakte_api


Есть сайт с уже работающей авторизацией.
Для сайта в VK создали приложение с типом веб-сайт.
Есть необходимость добавить возможность сайту от имени приложения отправлять сообщение
пользователям через VK API.
Возможно ли подобное? Насколько я понял, для приложений типа "сайт" доступны не все
методы.
Если возможно, то какой метод будет правильнее использовать?
    


Ответы

Ответ 1



На сегодня есть следующие варианты отправки сообщения пользователю ВК: от другого пользователя ВК messages.send(); от сообщества в ответ на запрос пользователя – Сообщения для бизнеса; уведомления от приложения secure.sendNotification(); платная отправка SMS secure.sendSMSNotification(). Варианты 1–3 не доступны приложению типа «Сайт». Но можно поступить так: Заведите аккаунт пользователя ВКонтакте, представляющий ваш сайт – вымышленный персонаж, директор, «лицо» сайта. Создайте приложение типа Standalone, и получите для него бессрочный токен с правами messages. Тут придётся всего один раз выполнить процедуру с копированием токена из адресной строки браузера. Зато теперь у вас есть токен, с которым вы сможете из скриптов сайта писать личные сообщения пользователям. Приходить они будут от имени того аккаунта. Скорее всего, пользователи будут что-то писать в ответ – обрабатывайте их ответы. Наладьте какой-то механизм на случай если токен вдруг перестанет работать – чтобы вы тут же узнали и выпустили новый.

Ответ 2



Вам нужно для такого получить access_token вручную, иначе не будет у него нужных прав. Для этого перейти по ссылке: http://oauth.vk.com/oauth/authorize?redirect_uri=http://oauth.vk.com/blank.html&response_type=token&client_id={app_id}&scope=friends,messages,offline В строке адреса скопировать access_token и использовать его для отправки сообщений: https://api.vkontakte.ru/method/messages.send?user_id={receiver_vk_id}&message={vk_msg}&title={vk_msg_title}&access_token={received_access_token} P.S. Параметр offline дает токену неограниченное время существования.

Метод рендеринга Гуро, формулы

#алгоритм #графика


Попытался разобраться в методе Гуро, но не могу понять значения переменных в формулах,
искал в гугле уже, но всюду не приводится их смысл. Что бы не вырывать из контекста
формулы прикрепляю две страницы из учебника



Поясните пожалуйста что это за переменные. И что значит освещенность в данном контексте,
как это связать с цветом? Или есть какой-то учебник совсем для чайников ? 
    


Ответы

Ответ 1



Прежде чем вдаваться в физический смысл формул - необходимо разобраться в трёх компонентах света - ambient, diffuse и specular. по приведённым вами формулам: Ia - ambient - фоновая мощность света, иначе говоря этот тот свет который материал воспринимает без рассеивания и зеркального отражения. Является постоянной величиной и не зависит от позиции ни объекта ни источника света. Ka - ambient - показывает степень материала воспринимать фоновый свет. Kd - diffuse (рассеивающая) составляющая материала - показывает степень материала воспринимать рассеивающий свет - тот свет который в зависимости от ориентации (нормали) поверхности и направления света рассеивается во все стороны равномерно. (n, l) - скалярное произведение векторов n - нормали к касательной плоскости к поверхности и l - вектора идущего из источника света в произвольную точку на изображении - при cos(n, l) == 1 произведение Kd * (n, l) даст Kd что будет означать максимальную яркость диффузной компоненты материала в этой точке, и при cos(n, l) = 0 наоборот, максимальную темноту соответствующего пикселя (или точки). Ks - specular составляющая материала - свойство материала воспринимать зеркальный свет (например сталь отражает свет с неким блеском). (v, r)^p - скалярное произведение между вектором отражённым от вектора света и видовым вектором (вектор идущий из позиции камеры в точку), в степени коеффициента фонга (p) - чем больше эта степень тем острее будет отражаться зеркальный свет - и аналогично с диффузным источником света когда угол между этими векторами 0 тоесть cos 0 == 1 зеркальное освещение достигает своего максимума (иначе говоря видовой вектор совпадает с вектором отражающий свет) и минимума когда угол прямой или больше прямого cos pi/2 == 0. p.s. специально не привожу вариант cos(n, h)^p который в вашем учебнике, так как обычно зеркальное отражение света зависит от направления взгляда v и отражённого от света вектора r, а там не ясно что имеется ввиду под векторами n и h. С помощью формул 11.1 и 11.2 вычисляется конечный цвет пикселя как сумма всех составляющих - в первом случае с учётом только эмбиентной и диффузных компонент, во втором с учётом всех трёх. Важно заметить, что модель Гуро вычисляя значения цвета во всех вершина полигона и интерполируя по этим точкам остальные значения иногда может приводить к потере аккурантности всего изображения по сравнению с моделей фонга, который вычисляет конечный цвет во всех точках (пикселях) делая результат более аккуратным но засчёт значительно большого количества вычислений.

Golang пакет time возвращение времени на русском

#golang


Здравствуйте, подскажите как правильно реализовать дату и время на русском в go?
    


Ответы

Ответ 1



Дата и время на русском это с месяцами/днями недели словами или просто в привычном формате? Если просто в ДД.ММ.ГГГГ ЧЧ:ММ:СС, то можно так fmt.Println(time.Now().Format("02.01.2006 15:04:05")) В отличие от php, c и т.п. в стандартном пакете Go символы форматирования это не буквы со спец-символами, а образцы. Например 02 это день месяца с ведущим нулём, 01 - номер месяца с ведущим нулём. Просто 2 это день месяца без ведущего нуля и т.п. В результате формат времени выглядит как представление даты 2006-01-02T15:04:05.999999999Z07:00 в том формате как вам нужно. Образцы можно посмотреть в константах пакета time https://golang.org/pkg/time/#pkg-constants

Как сделать, чтобы анимация не останавливалась

#java #android


Есть такая анимация:

android:duration="100"
android:fillBefore="false"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="0"
android:toXScale="0.9"
android:interpolator="@android:anim/decelerate_interpolator"
android:toYScale="0.9" />


Как работает: объект сначала уменьшается,а потом возвращается в исходное состояние.
(объект-ImageView)  

В коде обращаюсь так:

anim= AnimationUtils.loadAnimation(getContext(),R.anim.clickbutton);


и вызываю так:

public boolean onTouch(View v, MotionEvent event) {

           v.startAnimation(anim);
 switch (v.getId()) {
        case R.id.b1:
    {
           stopPlayerIfNeeded();
          playSample(soundsRawResIds[0]);
                        }
      break;


Все работает как часы, но хотелось бы, чтобы после нажатия анимация "постоянно работала"
т.е нажал я на case R.id.b1 - выполнилось действие, но анимация продолжала работать
до того момента, пока не выбрал другой R.id.* и т.к далее

/////////////////////////////////////////
как в этом случае остановить анимацию?сейчас так: 
выбрал R.id.b1: все запустилось и работает, выбрал R.id.b2: запустилась анимация
но и на R.id.b1: продолжает выполняться анимация,а нужно остановить 

for (int j = 0; j < arr_imageB.length; j++) {
arr_imageB[j].setOnTouchListener(new View.OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {

v.startAnimation(anim);
    switch (v.getId()) {
    case R.id.b1:
    {

            stopPlayerIfNeeded();
            playSample(soundsRawResIds[0]);

         }

    break;
case R.id.b2:

{
            stopPlayerIfNeeded();
            playSample(soundsRawResIds[1]);

        }

    break;
case R.id.b3:
{
            stopPlayerIfNeeded();
            playSample(soundsRawResIds[2]);

        }

    break;
case R.id.b4:
{
            stopPlayerIfNeeded();
            playSample(soundsRawResIds[3]);
         }

    break;
case R.id.b5: {
    stopPlayerIfNeeded();
    playSample(soundsRawResIds[4]);
}
    break;
case R.id.b6: {
    stopPlayerIfNeeded();
    playSample(soundsRawResIds[5]);

}

    break;
case R.id.b7:
{
            stopPlayerIfNeeded();
            playSample(soundsRawResIds[6]);

        }
    break;
}

    


Ответы

Ответ 1



Если анимация лежит в то атрибут android:repeatCount="infinite" должен работать

Ответ 2



Повесьте слушатель окончания анимации и в нём ещё раз её проиграйте, снова повесив слушатель: View viewToAnimate = ...; final int animResId = R.anim.anim_file; Animation anim = AnimationUtils.loadAnimation(ctx, animResId); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationEnd(Animation arg0) { Animation anim = AnimationUtils.loadAnimation(ctx, animResId); anim.setAnimationListener(this); viewToAnimate.startAnimation(anim); } @Override public void onAnimationRepeat(Animation arg0) { } @Override public void onAnimationStart(Animation arg0) { } }); viewToAnimate.startAnimation(anim); Так она будет повторяться ~бесконечно.

Ответ 3



Бесконечная анимация anim.setRepeatCount(-1); Остановка анимации v.getAnimation().setRepeatCount(0);

Golang: запись вида map[string]interface{}{}

#golang #map


Разбирая открытый код проекта, встретил вот такую запись

args := map[string]interface{}{}

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

Весь контекст в котором используется запись в качестве request передается route вида
controller/action в качестве Params как я понял json:

func (connect *Connect) Request(request string, params string) (interface{}, error) {
    req, err := connect.factory.NewRequest(Host)
    if err != nil {
        return nil, err
    }

    args := map[string]interface{}{}
    json.Unmarshal([]byte(params), &args)

    resp, err := req.Do(request, args)
    if err != nil {
        return nil, err
    }

    result, err := resp.GetMethodResult()
    if err != nil {
        return nil, err
    }

    return result, nil
}


Прошу приведите пример.
    


Ответы

Ответ 1



map[string]interface{} - это карта, где ключ string, а значение удовлетворяет типу interface{} interface{} - это пустой интерфейс, ему удовлетворяет любой объект (аналог void* из C) а последние "{}" это инициализация карты без значений (типа как map[int]int{1:2, 3:4} ) можно переписать в виде args := make(map[string]interface{}) или более развернуто type any interface{} var args map[string]any args = make(map[string]any,0) // или просто args = make(map[string]any)

Ответ 2



map[string]interface{} - это лишь указание типа, что ваша переменная типа ключ - строковая, и переменная типа interface{}. когда вы объявляете переменную такого типа: var a map[string]interface{} a["test"] = 1 \\ panic: assignment to entry in nil map , то будет ошибка. Нужно инициализировать пустую мапу: var a map[string]interface{} a = map[string]interface{}{} a["test"] = 1 , после чего, с ней можно работать.

Qt Баг с точностью после запятой в таблицах

#cpp #qt #mvc #tableview


Привет Всем, столкнулся с такой проблемой, во всех таблицах, базовых примерах да
и вообще Qt почему то допускает писать в таблицах значения только с точностью два знака
после запятой, не более. 
Как пример возьмем стандартный пример в Qt sqlbrowser.
Запускаем пример, заходим, видим в дереве 2 элемента Movies и Names, заходим в Movies,
далее в колонке Rating видим значения:
Например: 8,1
Нужно: 8,0001  , но больше двух цифр не вбивается после запятой, так во всех примерах QT.
Вопрос как данную проблему исправить, основываясь на этом примере?
Желательно привести данный участок кода, который разрешит эту проблему.
    


Ответы

Ответ 1



Это не баг, а просто соглашение, принятое в Qt по умолчанию для чисел с плавающей точкой. В одной задаче нужно показывать один знак после запятой, в другой все девяносто девять. Если не подходит количество, принятое по умолчанию, то создают собственный делегат - виджет, который предоставляет пользователю не только альтернативный вид данных в таблице, но и их редактирование. Файл delegate.h: #ifndef DELEGATE_H #define DELEGATE_H #include class Delegate : public QStyledItemDelegate { Q_OBJECT public: Delegate(QObject *parent = Q_NULLPTR); virtual QString displayText(const QVariant &value , const QLocale &locale) const; virtual QWidget *createEditor(QWidget *parent , const QStyleOptionViewItem &option , const QModelIndex &index) const; virtual void setEditorData(QWidget *editor , const QModelIndex &index) const; virtual void setModelData(QWidget *editor , QAbstractItemModel *model , const QModelIndex &index) const; }; #endif Файл delegate.cpp: #include "delegate.h" #include Delegate::Delegate(QObject *parent) : QStyledItemDelegate(parent) {} QString Delegate::displayText(const QVariant &value , const QLocale &locale) const { Q_UNUSED(locale); // Шесть знаков после запятой. return QString::number(value.toDouble(), 'f', 6); // Если нет необходимости в том, чтобы поле таблицы // содержало заканчивающие числа нули, то вместо // аргумента `f` нужно указать значение `g`. // return QString::number(value.toDouble(), 'g', 6); } QWidget *Delegate::createEditor(QWidget *parent , const QStyleOptionViewItem &option , const QModelIndex &index) const { Q_UNUSED(option); Q_UNUSED(index); QDoubleSpinBox *editor = new QDoubleSpinBox(parent); // Шесть знаков после запятой. editor->setDecimals(6); return editor; } void Delegate::setEditorData(QWidget *editor , const QModelIndex &index) const { QDoubleSpinBox *sbox = qobject_cast(editor); if(sbox != Q_NULLPTR) { sbox->setValue(index.model() ->data(index, Qt::EditRole).toDouble()); } } void Delegate::setModelData(QWidget *editor , QAbstractItemModel *model , const QModelIndex &index) const { QDoubleSpinBox *sbox = qobject_cast(editor); if(sbox != Q_NULLPTR) { model->setData(index, sbox->value(), Qt::EditRole); } } В методе Delegate::createEditor() строка editor->setDecimals(6) установит для делегата шесть знаков после запятой. Установка делегата в виджет таблицы: QTableView *view = new QTableView(); view->setModel(model); view->setItemDelegate(new Delegate(view));

Qt; Не запускается программа из под IDE

#cpp #qt #visual_studio_2013


Создал новый проект Qt под MSVS-2013, при запуске отладчика выскакивает ошибка об
отсутствии Qt5Cored.dll. При всем при этом предыдущие проекты написанные ранее, запускаются
без проблем. Люто-бешено реквестирую помощь. 

P.S.: Перед запуском конвертировал проект в QMake и обратно в Add-in как и положено.

P.P.S: 28.05 Проблема так и не решена. Неужели никто не сталкивался с такой темой?
    


Ответы

Ответ 1



Деревянное решение - добавить путь к DLL Qt в PATH. Если вы используете Qt Visual Studio Add-in, то эту работу должен выполнять он. Причем он делает это неявно, буквально обрабатывает событие о старте отладки и стартуемому процессу добавляет путь к DLL в его копию PATH (кажется при обычном неотладочном старте он делает то же самое). Соответственно путь этот вы должны указать в настройках проекта Qt. Сделано это для того, чтобы можно было компилировать проекты под разные версии Qt. Так вот, помнится, я сталкивался с тем, что аддин в этом месте глючил и прописывал путь через раз. Нашел раз и два. Попробуйте, как по первой ссылке человек пишет, пересобрать аддин. Вообще, очень сложно судить почему ваша пограмма на вашей машине не находит DLL. Вы писали, что раньше работало, посмотрите что вы делали с системой в этот промежуток времени. И еще, в соотвествии с МСДН проверте все ли у вас настроено правильно.

Ответ 2



Проверьте настройки проекта. Скорей всего ошибка в линковщике (неправильно прописан или не прописан путь)

Ответ 3



Есть кривое, абсолютно корявое решение, но оно дает хоть что-то - таскать нужные dll в папке с проектом. Я понимаю что так не правильно, но другого решения не нашел.

Регулярное выражение для строки, состоящей только из кириллицы, латиницы и пробелов

#php #регулярные_выражения


Нужна проверка на присутствие в строке символов. Строка должна содержать только символы
кириллицы, латиницы, пробелы и ничего кроме. Пробовал как в js регулярку составить,
но почему-то работает совсем неправильно!

 if (preg_match("/[^A-zА-я]/","daksks sdsd ывыв1234234") == 0) {
 echo "Да";
 }

    


Ответы

Ответ 1



preg_match( "/[^a-zа-яё ]/iu", $text ); Только кириллица, латиница и пробел.

Ответ 2



Вы можете воспользоваться следующим вариантом

Подскажите регулярки для строки содержащей больше 1-2 слов?

#регулярные_выражения


Подскажите пожалуйста регулярки:


"строка содержит более одного слова"
"строка содержит более двух слов"

    


Ответы

Ответ 1



Да тупо в лоб. строка содержит более одного слова /\w+\s+\w+/ строка содержит более двух слов /\w+\s+\w+\s+\w+/ При условии, что разделителем между словами считаем именно \s (то есть знаки препинания не учитываем).

Ответ 2



строка содержит более N слов Рассмотрим общий случай. Слова могут разделять любые символы, которые не относятся к буквам, то есть символьный класс \W Слово, соответственно, будет \w+ (?:\w+\W+){N}\w Это общий вид выражения. В случае, N = 1 можно упростить до такого: \w\W+\w В случае N = 2 будет выглядеть так: (?:\w+\W+){2}\w

c# Как продолжить скачивание после обрыва соединения с интернетом

#c_sharp


Скачиваю файл, но после как интернет снова в бою, он не продолжает загрузку 
Как исправить? 

WebClient web = new WebClient();
web.DownloadFileAsync(Uri, Path, DWMVC);


P.S: Нужно чтобы при отключения интернет соединения,останавливалась загрузка файл,
а после возобновления интернета,снова качала оставшие файлы!
    


Ответы

Ответ 1



На основе кода из ответа @AkaInq (добавил using и проверку кода возврата): var request = WebRequest.CreateHttp(uri); var fi = new FileInfo(path); var havePart = fi.Exists; if (havePart) request.AddRange(fi.Length); using (var response = (HttpWebResponse)request.GetResponse()) { var partialDownload = havePart && response.StatusCode == HttpStatusCode.PartialContent; using (var file = File.Open(path, partialDownload ? FileMode.Append : FileMode.Create)) using (var net = response.GetResponseStream()) net.CopyTo(file); } Добавьте try/catch в нужном месте по вкусу.

Ответ 2



вот как-то так, правда это не через webclient: static void DownloadFile(string sSourceURL, string sDestinationPath) { long iFileSize = 0; int iBufferSize = 1024; iBufferSize *= 1000; long iExistLen = 0; System.IO.FileStream saveFileStream; if (System.IO.File.Exists(sDestinationPath)) { System.IO.FileInfo fINfo = new System.IO.FileInfo(sDestinationPath); iExistLen = fINfo.Length; } if (iExistLen > 0) saveFileStream = new System.IO.FileStream(sDestinationPath, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite); else saveFileStream = new System.IO.FileStream(sDestinationPath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite); System.Net.HttpWebRequest hwRq; System.Net.HttpWebResponse hwRes; hwRq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(sSourceURL); hwRq.AddRange((int)iExistLen); System.IO.Stream smRespStream; hwRes = (System.Net.HttpWebResponse)hwRq.GetResponse(); smRespStream = hwRes.GetResponseStream(); iFileSize = hwRes.ContentLength; int iByteSize; byte[] downBuffer = new byte[iBufferSize]; while ((iByteSize = smRespStream.Read(downBuffer, 0, downBuffer.Length)) > 0) { saveFileStream.Write(downBuffer, 0, iByteSize); } }

Загрузка картинок из ссылки

#java #android #imageview


Есть список, в каждом элементе должна быть картинка. 
Картинки в виде http ссылок.  

Неужели нет способа подгрузить картинки в основном потоке, не заморачиваясь с созданием
новых потоков? 
    


Ответы

Ответ 1



Конечно же есть! для этого можете воспользоваться библиотекой Picasso Необходимо добавить ее к проекту записью в градл файл: compile 'com.squareup.picasso:picasso:2.5.2' Использовать очень просто Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

Ответ 2



Используйте библиотеки, Picasso или UniversalImageLoader, они все сделают за вас

Ответ 3



Да пожалуйста, хотите основной поток, юзайте)): StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); Только смысл морозить основной поток, приложение будет не юзабельным.

Android - как отправлять запрос с периодичностью 10 секунд на сервер? [закрыт]

#java #android


        
             
                
                    
                        
                            Закрыт. Этот вопрос необходимо уточнить или дополнить
подробностями. Ответы на него в данный момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Добавьте больше подробностей
и уточните проблему, отредактировав это сообщение.
                        
                        Закрыт 3 года назад.
                                                                                
           
                
        
Как отправлять запрос с периодичностью  10 секунд на сервер? Я использую библиотеку
okhttp, скиньте пример, пожалуйста.
    


Ответы

Ответ 1



Timer timer = new Timer(); TimerTask timerTask = new TimerTask() { @Override public void run() { //Тут идёт запрос в сеть } } timer.schedule(timerTask, 0, 10000);

Ответ 2



RxJava, с лямбдами Observable.just(true).repeatWhen(t->t.delay(10,TimeUnit.SECONDS)).subscribe(b->{makeNetworkRequest();}); Без лямбд Observable.just(true).repeatWhen(new Func1, Observable>() { @Override public Observable call(Observable t) { return t.delay(10, TimeUnit.SECONDS); } }).subscribe(new Action1() { @Override public void call(Boolean b) { makeNetworkRequest(); } });

Ответ 3



В Android предоставлено множество способов создать таймер. Запрос на сервер через библиотеку okhttp можно сделать синхронным в отдельном потоке. Мой пример с созданием рекурсии, без использования Timer и TimerTask. static boolean stopSyncDownloadData = false; /** * Call method in thread * @param stopSyncDownloadData - boolean */ private void syncDownloadData() { if (stopSyncDownloadData) return; Request request = new Request.Builder().url(url).build(); Response response = client.newCall(request).execute(); // parse response // update UI // delay Thread.sleep(10000); // sleep syncDownloadingData(); } Ниже пример для создания простейшего потока: new Thread(new Runnable() { public void run() { syncDownloadData(); } }).start();

CS:GO получить сылку на файл .dem

#php #nodejs #steam_web_api


Нужно получить ссылку файл в формате .dem по коду демо (как пример код CSGO-OyjY3-pPKCF-cmpHJ-wdohh-CY5dK) 

Нужная ссылка выглядит так http://replay124.valve.net/730/003072985384448163905_0699089210.dem.bz2
, но как по коду  демо получить значения:


003072985384448163905
0699089210
124


Хотелось бы сделать на PHP но можно и на NodeJS, но не нашёл ничего на эту тему в
интернете.

Up:
 В самой игре демо можно скачать по внутреней консоли игры командой csgo_download_match
код демо например csgo_download_match CSGO-pj5MV-zyzpa-PaHVb-tFUwV-HGXbD, но всеравно
как оно расшифровывет в ссылку остаётся загадкой
    


Ответы

Ответ 1



Ваша проблема уже решена, более того, есть библиотека для nodejs https://www.npmjs.com/package/csgo А вот и код, который расшифровывает ваш код: var scDecoder = new csgo.SharecodeDecoder("CSGO-U6MWi-hYFWJ-opPwD-JciHm-qOijD"); console.log(scDecoder.decode()); В репе есть более полный пример, используйте его. -- Внутриигровой загрузчик использует функцию CMsgGCCStrike15_v2_MatchListRequestFullGameInfo из внутренней библиотеки NetHook2.dll UPD: Вот метод,который использует эти функции, даже называется также https://github.com/joshuaferrara/node-csgo/blob/master/handlers/match.js#L77

Ответ 2



Можно поглядеть тут (c#) Функция generatematchlist https://github.com/akiver/CSGO-Demos-Manager/blob/04b44968a4d3c70664e1b3c85c93f5e68ca9a5d2/src/ViewModel/HomeViewModel.cs

Ответ 3



Ну кто так задаёт вопросы?! Какую именно ссылку нужно создать? Но, если как я понимаю, нужно отдать файл по определенному запросу, то примерно так когда то давно делал. if($_GET['code'] == 'CSGO-OyjY3-pPKCF-cmpHJ-wdohh-CY5dK') { Header("HTTP/1.1 200 OK"); Header("Connection: close"); Header("Content-Type: application/pdf"); Header("Accept-Ranges: bytes"); Header("Content-Disposition: Attachment; filename=new_filename.pdf"); Header("Content-Length: 50000"); readfile('test_file.pdf'); }

Проверка на нахождение в enum. Java

#java #enum


Как проверить нахождение константы в enum'e, которая соответствует введенной строке
с консоли? 
    


Ответы

Ответ 1



Для enum-а: enum Foo { VALUE1, VALUE2 } Проверить есть ли в нем значение переменной inputString String inputString = ... boolean exists = true; try { Foo.valueOf(inputString); } catch (IllegalArgumentException e) { exists = false; } для строки inputString = "VALUE1" переменная exist будет true

Ответ 2



Можно использовать библиотеку guava Зависимость: com.google.guava guava 19.0 Код: com.google.common.base.Enums.getIfPresent(EnumClass.class, value).orNull()

Построить график c#

#c_sharp #winforms #график


Добрый день, подскажите пожалуйста, как построить график многочлена :
сам многочлен p(x)=An*X^n + An-1*X^n-1+...+A1X+A0

 int[] array= new int[10];
int i, num, power;
float x;

num=4;
x=1;

array[0] = 3;
array[1] = -5;
array[2] = 6;
array[3] = 8;
array[4] = -9;

power = num;

double k = 0;

for (i = 0; i <= num; i++)
{
    k += Math.Pow(x, power--) * array[i];
 //   richTextBox1.AppendText(Convert.ToString(k) +"\n");

}


как щас построить график ?
    


Ответы

Ответ 1



Для начала вам будет достаточно стандартного класса Chart, хотя есть и сторонние компоненты для построения красивых графиков, но мне кажется, что сначала лучше разобраться со стандартным контролом. В документации на MSDN есть довольно подробный Tutorial. Основные моменты покажу в коде, подробности в официальной документации. class ChartForm : Form { public ChartForm() { //создаем элемент Chart Chart myChart = new Chart(); //кладем его на форму и растягиваем на все окно. myChart.Parent = this; myChart.Dock = DockStyle.Fill; //добавляем в Chart область для рисования графиков, их может быть //много, поэтому даем ей имя. myChart.ChartAreas.Add(new ChartArea("Math functions")); //Создаем и настраиваем набор точек для рисования графика, в том //не забыв указать имя области на которой хотим отобразить этот //набор точек. Series mySeriesOfPoint = new Series("Sinus"); mySeriesOfPoint.ChartType = SeriesChartType.Line; mySeriesOfPoint.ChartArea = "Math functions"; for (double x = -Math.PI; x <= Math.PI; x += Math.PI / 10.0) { mySeriesOfPoint.Points.AddXY(x, Math.Sin(x)); } //Добавляем созданный набор точек в Chart myChart.Series.Add(mySeriesOfPoint); } } Вот собственно минимум кода для рисования графика на форме. Здесь не приведены ни настройки осей координат и сетки, ни другие графические рюшечки которые поддерживает данный контрол, т.к. примеры применения практически всех возможностей этого контрола есть в официальной документации, ссылка выше. Дополнение: Вам нужно вычисление многочлена вынести в отдельную функцию. Это можно сделать например так double Polynom(double x, double[] coefficients) { double y = 0.0; double currentX = 1.0; for(int i = 0; i

Google Places API for Android

#android #google_places_api


Всем добра! Ребята, нужна ваша помощь. 

Как правильно сгенерировать BROWSER_API_KEY_FOR_PLACES для Google Places API for Android?


Что нужно выбрать? для https://maps.googleapis.com/maps/api/place/details/json?,
https://maps.googleapis.com/maps/api/place/nearbysearch/json?

Update: Разобрался.
    


Ответы

Ответ 1



Практически во всех туториалах пишут следующее: We can create API key for Google Place API by clicking “Create new Browser key” available at the “API Access” pane of the Google console. Also ensure that, “Places API” is enabled in the “Services” pane of the Google console. Коварная строка Create new Browser key, которая заставила меня помучиться. Так вот "Что нужно выбрать? для https://maps.googleapis.com/maps/api/place/details/json?, https://maps.googleapis.com/maps/api/place/nearbysearch/json?" Во-первых нам пригодится следующее из подключенных API: Тут же мы можем увидеть запросы, которые прошли или не прошли (как доказательство тому, что ключ используется нужный): И еще, чтобы проверить правильный ли ключ используется, пробейте запрос в браузере: https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=32.1145134,34.8269532&radius=5000&types=parknig&sensor=true&key=AIzaSyDqqAdbsJwVT8LbjY0sGFXeiJBwCiUFV70 Только ключ поменяйте на свой) Во-вторых создавать нужно !Ключ для сервера!, а не для браузера: Туториал, который я использовал староват, но рабочий (в плане кода - инфа 100), а из библиотек достаточно таки будет подключить compile 'com.google.android.gms:play-services-maps:...'. P.S. Надеюсь ответ кому-нить пригодится:)

Как открыть стороннее приложение из своего приложения?

#java #android


Мне нужно использовать стороннее приложение в своем проекте(просмотр 3d моделей).
Можно ли как то допустим при нажатии на кнопку в своем приложении открывать нужное
мне приложение? Может как то программно запускать его исполняющий файл?
    


Ответы

Ответ 1



самостоятельно Вы приложение пользователя не запустите, это должен сделать он сам,но реализовать диалог выбора приложений, которые могут обработать Ваш запрос вы можете при помощи неявного intent. Таким образом, сделать запрос на запуск стороннего приложения Вы сможете. Но важно, чтобы приложение,которое Вы хотите запустить явно уведомляло Андроид , посредством своего манифеста,о том, что его можно запускать из вне.

Ответ 2



В итоге я сделал это так public void reeee(View view) { String path = "/storage/emulated/0/Android/data/com.example.android.camera2basic.demo/files/default/AvatarModelDir/Anna.dae"; File file = new File(path); //checking if the File exists if(file.exists()) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/octet-stream"); boolean result = isIntentAvailable(getApplicationContext(), intent); if (result){ startActivity(intent); } } } public static boolean isIntentAvailable(Context context, Intent intent) { List list = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return !list.isEmpty(); } Указывая путь к файлу который нужно открыть и правильный тип MIME (в моем случае это application/octet-stream) у меня все работает

Android - как правильно добавлять картинку на button

#java #android


Имеется png картинка и цель - добавить её на button. Проблема в том, что если добавляю
через @android:background кнопки, то картинка становится с лесенками (как будто антиалиазинг
выключен), либо становится мутной.
Если использую разметку ниже, то вообще картинка не показывается, остаются только
границы на button.



    
        
        
            
                
                

                
            
        
    


    
        
        
            
                
                

                
            
        
    





Имеются предоположения, что неправильно добавляю png в проект. Добавляю через
res->new->image asset

Исправил, теперь всё работает





    
        
            
        
        
            
                
                
                
            
        
        



    
        
            
        
        
            
                
                
                
            
        
    





Картинку перемещаю вручную в папку res/drawable-hdpi
Только есть небольшая проблема, что селектор android:state_pressed="true" всё равно
отказывается работать
    


Ответы

Ответ 1



По описанию проблема в том, что нет ресурса с достаточным качеством картинки. Либо ресурс с соответствующим квалификатором отсутствует вовсе (например res/drawable-xxhdpi/), либо хранящееся в нем изображение имеет низкое качество - собственный размер в пикселях мал для данного разрешения или достаточный размер, но неудачный скалинг, то есть размер нормальный, но в результате обработки по увеличению получилась хрень вместо четкой картинки. Так, для экрана плотностью XXHDPI (~480dp) изображение для стандартной иконки (размер 48x48dp) должно иметь абсолютные геометрические размеры 144x144 пикселя с содержимым соответствующего качества (подробнее смотрите офф.документацию). В первом случае недостающие ресурсы нужно создать, во втором посмотреть, что там за изображения вообще лежат и привести их в соответствие. PS: селектор у вас составлен неверно. В конце селектора должен быть айтем для вида по умолчанию, который не имеет никаких стейтов (в вашем случае вместо должен быть просто и располагаться самым последним в иерархии айтемов. Выбор айтема в селекторе производится по следующему алгоритму: проверяется условие стейта первого айтема, если совпадает, то он выводится и селектор заканчивает работу, иначе переходит ко второму айтем и проверяет его условие и так далее, если ни одно из условий не выполняется последним выполняется айтем без условий, который содержит, как правило, нормальный вид (состояние без всяких нажатий, фокусов, селекторов и тд). Картинку в селекторе не видно, потому что ее закрывает shape - фигуры не прозрачные по умолчанию. Смотрите, например этот ответ (вторая часть) по созданию вида из наложения картинки и шейпа.

Ответ 2



Подробная документация от Google расскажет о Button ссылка на документацию А так же можно почитать о файлах ресурсов ссылка на документацию по поводу ресурсов Так же, что бы избежать деформации картинки, советую изучить такую вещь как VectorDrawable, по ссылке выше есть описание.

Ответ 3



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

Как отсортировать текстовый список файлов по расширению?

#linux #bash


Есть файл log.txt. В этом файле содержится громадный список файлов и расширений,
где каждое новое название начинается с новой строчки, приблизительно вот так:

1.jpg
common.pdf
script.sh
Justin Bieber - Baby.mp3


Нужно перекинуть весь список в еще один файл, в котором список файлов будет упорядочен
по расширению.
    


Ответы

Ответ 1



можно, например, воспользоваться программой sort, передав ей две опции: указание использовать в качестве разделителя полей точку: -t. указание сортировать по второму полю: -k 2 $ sort -t. -k 2 исходный-файл > отсортированный-файл уточнения: так называемые «расширения» файла пришли к нам из файловой системы fat16 (а в неё — из файловой системы для операционной системы cp/m), где это были отдельные сущности. с тех пор данное понятие присутствует лишь по традиции и довольно условно. в операционных системах же системах unix и их «наследниках» (bsd, gnu и т.п.) этого понятия не существовало изначально: имя файла, например, file.tar.gz, — это цельная сущность, в ней нет никаких «расширений». да, строку .tar.gz можно считать «суффиксом» в имени файла. или даже двумя суффиксами: tar и gz. потому мой ответ и содержит предложение выделить в имени файла первую точку, подразумевая, что после неё и находится суффикс имени файла, или, в традиционно-устаревшей терминологии — «расширение». если же всё-таки требуется сортировка по самому последнему суффиксу в имени файла, т.е., чтобы файл с именем a.z.a был раньше файла с именем a.b, то можно, например, воспользоваться такой конструкцией (она будет корректно работать при наличии любых символов в исходном файле, и вертикальной черты, и символа табуляции): $ rev исходный-файл | sed -r 's/^([^.]+).*/&\t\1/' | rev | sort | cut -f 2- > отсортированный-файл

Ответ 2



Можно ввести временное поле с расширением файла, отсортировать по нему, а затем удалить это поле. Пример: $ while read F; do printf '%s|%s\n' "$(echo "$F" | sed 's|.*\.\([a-zA-Z0-9]\+\)$|\1|')" "$F"; done

Ответ 3



Можно вытащить расширение с помощью awk (переменная $NF хранит последнее поле - т.е. расширение), прилепить его к началу каждой строки, отсортировать нормальным образом и затем удалить лишнее из начала строки: awk -F. '{ printf "%s\t%s\n", $NF, $0 }' file | sort | cut -f2-

Пятиугольная кнопка

#html #css #html5 #css3 #svg


Здравствуйте. Весь день бьюсь над этой кнопкой. Пробовал делать уголок с помощью
border - не работает градиент. Пробовал поворачивать див на 45 градусов - угол стрелки
получается 90 градусов, а на картинке угол тупой. Пробовал рисовать на SVG - не знаю,
как сделать круглые углы. Подскажите как это сделать?





Если видели где-нибудь похожую кнопку - поделитесь ссылкой на страничку.
    


Ответы

Ответ 1



*{ box-sizing: border-box; } .btn{ display: inline-block; padding: 16px 30px; color: #fff; border: 1px solid #4A803C; position: relative; border-radius: 3px; background: rgb(74,168,28); /* Old browsers */ background: -moz-linear-gradient(top, rgba(74,168,28,1) 0%, rgba(63,155,19,1) 100%, rgba(56,146,12,1) 100%); /* FF3.6-15 */ background: -webkit-linear-gradient(top, rgba(74,168,28,1) 0%,rgba(63,155,19,1) 100%,rgba(56,146,12,1) 100%); /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(to bottom, rgba(74,168,28,1) 0%,rgba(63,155,19,1) 100%,rgba(56,146,12,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4aa81c', endColorstr='#38920c',GradientType=0 ); } .btn > span{ position:relative; z-index: 1; } .btn:after { content: ""; width: 35px; height: 35px; display: block; position: absolute; top: 7px; right: -18px; border: 1px solid #4A803C; border-left: none; border-bottom: none; border-radius: 3px; -webkit-transform: rotateY(45deg) rotate(47deg) skew(5deg); transform: rotateY(45deg) rotate(47deg) skew(5deg); background-image: -moz-linear-gradient( 143deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: -webkit-linear-gradient( 143deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: -ms-linear-gradient( 143deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: linear-gradient( 143deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); } .btn:hover{ background: rgb(56,146,12); /* Old browsers */ background: -moz-linear-gradient(top, rgba(56,146,12,1) 0%, rgba(63,155,19,1) 0%, rgba(74,168,28,1) 100%); /* FF3.6-15 */ background: -webkit-linear-gradient(top, rgba(56,146,12,1) 0%,rgba(63,155,19,1) 0%,rgba(74,168,28,1) 100%); /* Chrome10-25,Safari5.1-6 */ background: linear-gradient(to bottom, rgba(56,146,12,1) 0%,rgba(63,155,19,1) 0%,rgba(74,168,28,1) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#38920c', endColorstr='#4aa81c',GradientType=0 ); } .btn:hover:after{ background-image: -moz-linear-gradient( -47deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: -webkit-linear-gradient( -47deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: -ms-linear-gradient( -47deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); background-image: linear-gradient( -47deg, rgb(74,168,28) 0%, rgb(63,155,19) 100%); } Умножитель матрицы Fiddle

Ответ 2



Почему бы не отрисовать кнопку в векторном редакторе и не вывести SVG из него? Наскоро в Adobe Illustrator, скругление кривое – через Filter - Stylize - Round corners. А по-хорошему его надо делать дугами окружностей, с правильным прилипанием к пиксельной сетке. Вместо Иллюстратора, Sketch или Fireworks наверное, больше подойдёт.

Размытие Blur на фон блока

#html #css


Есть секция, которая содержит вложенные блоки, картинки и тд. На этой секции фоном
задана картинка, но мне её нужно размыть так, чтобы другие элементы оставались не тронутыми.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius et ea nemo deleniti natus aliquid

Скажите пожалуйста, как это сделать? Нужно чтобы был размыт только фон.


Ответы

Ответ 1



Вариант 1 .test{ position: relative; min-height: 400px; } .test:before{ content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('http://www.ufunk.net/wp-content/uploads/2016/01/ValentinValkov-2.jpg') no-repeat center top; background-size: cover; -webkit-filter: blur(5px); filter: blur(5px); } .test p{ position: relative; z-index: 1; }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius et ea nemo deleniti natus aliquid

Вариант 2 .test{ position: relative; min-height: 400px; } .img-bg-test{ position: absolute; top: 0; left: 0; width: 100%; max-height: 100%; -webkit-filter: blur(5px); filter: blur(5px); } .test p{ position: relative; z-index: 1; }

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eius et ea nemo deleniti natus aliquid



bash script для создания папок

#linux #bash


Есть множество папок dir1, dir2, dir3 и тд, общее количество - 100-200, к примеру.
Нужен скрипт, который создаст около них папки типа dir1fold, dir2fold, dir3fold(грубо
говоря, берётся название предыдущей папки и добавляется префикс fold) и, в идеале,
перенесёт каждый dir в свой dirfold.
    


Ответы

Ответ 1



for dir in *; do if [ -d "$dir" ]; then newdir="${dir}fold" mkdir "$newdir" mv "$dir" "$newdir" fi done

Вывести адрес, под которым машина отправляет запросы к 8.8.8.8 (DNS)

#linux #bash #shell #dns


Задание:

Выведите IP адрес под которым машина отправляет запросы к 8.8.8.8 (учитывать NAT
после выхода пакета из машины не нужно, нужен IP адрес с которым пакет покидает машину).

Нужно написать Bash-скрипт. Как я понимаю, нужно понять где у нас в локальной сети шлюз.

На данный момент готово следующее:

используем tcpdump -
tcpdump -i any 'udp port 53' > whoIP - таким образом результат дампа со всеми запросами
на 53 порт(т.е. DNS) сохраняется в файл.

Файл содержит следующие строки:

15:09:44.365818 IP 192.168.0.102.11996 > 192.168.0.1.domain: 31675+ A? www.google-analytics.com.
(42) 

15:09:44.398267 IP 192.168.0.1.domain > 192.168.0.102.11996: 31675 7/0/0 CNAME www-google-analytics.l.google.com., A

затем при помощи "Адского" выражения:
cat whoIP | grep A? | grep -E -o '>+ ([0-9]{1,3}[.]){3}[0-9]{1,3}'| grep -E -o "([0-9]{1,3}[.]){3}[0-9]{1,3}"

Логика его такова:


cat whoIP |grep A?  - в файле мы ищем строки содержащие запрос на разрешении имени.
tcpdump помечает такие строки A? 
| grep -E -o '>+ ([0-9]{1,3}[.]){3}[0-9]{1,3}' - данное регулярное выражение ищет
IP-адрес в формате ipv4.
в строке мы ищем следующую конструкцию "> "ipv4 адрес"" - в tcpdump ">" означает
от кого к кому идет запрос. Нас интересует к кому.
| grep -E -o "([0-9]{1,3}[.]){3}[0-9]{1,3}" - из найденного фрагмента "к кому" вырезаем
только адрес.Данное выражение от предыдущего отличается лишь отсутствием "<"

В целом мой алгоритм следующий:


1.Запустить tcpdump и перенаправить его вывод в файл whoIP


Послать в другом терминал DNS-запрос при помощи dig
ОСТАНОВИТЬ TCPDUMP ctrl+c
grep файл


Во-первых, проблема в том, что в скрипт данную последовательность я заложить не могу,
т.к. tcpdump работает пока ему не послать сигнал завершения( вот тут и загвоздка).
Если в скрипте ищет запуск tcpdump, то следующие команды не исполняются, т.к. tcpdump
работает бесконечно.

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


Ответы

Ответ 1



Если это работает, то значит имеет право на жизнь. А tcpdump можно заставить работать как нужно. для начала нужно его запустить в фоне tcpdump .... параметры .... & символ & важен - он отправляет процесс в фон и можно будет продолжить скрипт дальше. Так как нам нужно будет потом его остановить, то следующей строкой запоминаем его pid. TDPID=$! эта строка должна быть сразу. Иначе она запомнит другой PID. TDPID - это просто переменная. дальше вставляете свой код. Когда нужно будет tcpdump остановить, просто посылаем ему Ctrl+C kill -3 $TDPID P.S. Важный момент, на который все натыкаются и долго не могут понять, что не так. В строке TDPID=$! не должно быть пробелов. Если написать так TDPID = $!, то работать не будет.

Ответ 2



Мне кажется, должно быть более простое решение. совершенно верно. если речь идёт о сетевой подсистеме программы linux версии выше или равной 2.0 (или 2.1? никак не могу запомнить), то можно воспользоваться программой ip: $ ip route get 8.8.8.8 8.8.8.8 via 192.168.0.1 dev eth0 src 192.168.0.2 cache в приведённом примере вывода 192.168.0.2 — это и есть ip-адрес, с которым будут покидать систему пакеты, адресованные к 8.8.8.8. если полный вывод программы не подходит, и этот адрес надо извлечь, то для удобства обработки можно добавить опцию -o (oneline): $ ip -o route get 8.8.8.8 8.8.8.8 via 192.168.0.1 dev eth0 src 192.168.0.2 \ cache и извлечь его с помощью, например, программы sed (кстати, параметры route и get в данном случае можно сократить до одной буквы): $ ip -o r g 8.8.8.8 | sed 's/.*src \([^ ]\+\) .*/\1/' 192.168.0.2 подробности смотрите в документации к программе ip: man ip, man ip-route. кстати, маршрутов может оказаться и более одного (например, при использовании на данной машине динамической маршрутизации). они все будут отображены, и, следовательно, в окончательном выводе будет более одной строчки с ip-адресами.

Как сделать переход на другое активти без возможности перехода на старое?

#android #activity


К примеру есть активти1 , активити2 и активити3, к примеру я сначала перешел на активити2
а от туда на активити3, но потом мне захотелось перейти с активити3 на активити1, я
делаю переход, но если я нажму кнопку назад то меня с активити1 перебросит на активити3
обратно, как избежать этого перехода ?
    


Ответы

Ответ 1



во втором activity после startActivity вызывайте finish(), В третьем активити вместо startActivity, вызывайте finish(). Тогда такой ситуации не повторится.

Ответ 2



Если активити2 никогда не должна быть в стеке активити, то можно просто прописать параметр android:noHistory="true" для этой активити и не морочится со всякими финишами и стартами. Пример как это должно выглядеть в манифесте:

Ответ 3



Как вариант - переопределить метод нажатия на кнопку "назад" и вместо стандартного действия запустить нужную активити: @Override public void onBackPressed() { Log.i(LOG, "onBackPressed"); Intent intentToActivity = new Intent(this, ACTIVITy_CLASS_NAME.class); startActivity(intentToActivity); }

Узнать количество членов enum

#cpp


Как узнать количество членов enum?

Пусть в классе задаю enum: enum a{a1,a2,a3,a4,a5};, а в другом классе есть метод,
который перебирает значения вектора по членам a с помощью for(int...). Но если я потом
увеличу количество членов a, то придется менять это и в методе. И хотелось бы задавать
размер вектора от размера a.

Или узнать какой элемент последний.
    


Ответы

Ответ 1



Узнать кол-во констант в перечислении не представляется возможным. Если вы используете проход по циклу, то может быть достаточно просто задать константу, говорящую о максимальном размере. Ну, или если всё же хочется иметь именованные константы, то можно в enum задать последний элемент как aMax: enum A { a1, a2, a3 ... , aMax }; Цикл в таком случае будет выглядеть так: for( A v = a1; v < aMax; ++v ) { ... } Добавлю, что вся эта схема работает, только при отсутствии разрывов в значениях перечисления. Например: enum A { a1, a2 = 100, a3 ... , aMax }; породит проблему отсутствия значений в диапазоне [1..99]. Т.е. цикл должен как-то это учитывать, а не идти обычным инкрементом.

Для чего нужен код (хэштег) в конце сайта?

#html #url #веб_программирование


Последнее время заметил код (или хэштег) в адресной строке в конце многих сайтов. 
К примеру: https://site.ru/blablabla/#.V49UWuLLfK4

Причем при каждом обновлении страницы он меняется, а ссылка работает и без него.
Особенно этим грешит medium.com. Для чего это нужно и как это сделать? 

Только не пишите про якори. Это не они.
    


Ответы

Ответ 1



Эта часть URL называется "идентификатор фрагмента" (fragment identifier). Кусок URL, извлечь смысл из которого должен клиент, а не сервер. Поэтому, запрашивая документ по HTTP, клиент может эту часть в запросе даже не передавать (возможно, даже обязан не передавать, но надо глянуть в стандарт). Это семантически и высокоуровнево. Поначалу (и уже довольно давно) эта часть использовалась только для якорей в браузерах. Сервер возвращает весь документ, а клиент смотрит в фрагмент, ищет соответствующий якорь и проскролливает вид до него исключительно ради удобства пользователя. Это вы знаете. С распространением JavaScript к этой части появился доступ не только у браузера, но и у произвольного кода, присланного сервером. И эта часть стала неплохим местом для хранения небольшого кусочка клиентских данных, о которых серверу знать необязательно, а клиент как-то может отреагировать. Для чего? Ну, для всего, что умеет JavaScript, нужно только применить воображение. Сейчас это применяется для хранения состояния в небольших SPA прямо внутри ссылки. Это необязательно должен быть именно SPA, это может быть любое браузерное приложение на JS, возможно даже размещённое на нескольких страницах. Просто это короткий термин и понятно о чём. Ссылку клиент А может послать клиенту Б какими-то своими способами, и, открыв её, можно увидеть приложение точно в том же состоянии, в каком оно было у клиента А. Пример: Coriolis.io, инструмент для обмена сборками кораблей в Elite: Dangerous. Ещё вариация — хранение не всего состояния приложения, а только той части, которая может быть полезна другим пользователям. Например, роутинг. URL вида http://site.com/#/thing/42 Он осуществлялся в основном через фрагментную часть. Это пока не было HTML5 History API. Теперь есть. И теперь когда сервер можно научить понимать любые URL, можно писать SPA, меняющие "текущий URL" в пределах одной страницы без подобных костылей. AngularJS без "HTML5 mode" работает таким образом. Когда программируемой серверной части нет (или её лень настроить, что бывает), это единственный способ клиентского роутинга, который не ломает получающиеся ссылки: ведь фрагментную часть сервер игнорирует. Или обмен токенами. Некогда было засилье мессенджеров, работающих через WebRTC, и через фрагментный кусок образовывались комнаты. SPA ищет там токен комнаты, если не находит — генерирует случайный и добавляет его туда. Пользователю остаётся только скинуть ссылку. Перешедшие по ней попадут в SPA, а JS-клиент в нём увидит токен и сразу попросится в указанную комнату, попав к тому, кто ссылку скинул.

Разделение строки в массив

#php #регулярные_выражения


Подскажите как решить задачу, мне нужно разбить строку в массив:

    $s = "бла бла бла Сила+5 бла бла бла Ловкость+12 бла бла бла Шанс-2";


разделителем я хотел сделать пробел которому предшествует цифры:

    $a = preg_split("/\d+\s+/", $s);


но так я отсекаю сами числа которые мне нужны.


бла бла бла Сила+
бла бла бла Ловкость+
бла бла бла Шанс-

    


Ответы

Ответ 1



Можно воспользоваться ретроспективной проверкой "; print_r($a);

проверка введённого пользователем пин-кода

#javascript


Хочу чтобы функция возвращала true если пользователь ввёл 4 или 6 цифр. И false во
всех остальных случаях. Ввёл буквы, больше символов и т.д.

validatePIN("1234") === true
validatePIN("12345") === false
validatePIN("a234") === false


Код функции: 

function validatePIN (pin) {
  //return true or false
  if (pin.length == 4) {
    return true;
  } else if (pin.length == 6) {
    return true;
  }

  return false;

}


Как мне грамотно организовать проверку, того что в строке нет символов, кроме цифр
от 1 до 9.

Решение с помощью регулярного выражения:

^(\d{4}|\d{6})$


П.с. если кто знает покажите как сделать без RegExp
    


Ответы

Ответ 1



Ну если без регулярок, то вот так: function validatePIN(pin) { var i = pin.length; if (i != 4 && i != 6) { return false; } while (i--) { if (pin[i] < '0' || pin[i] > '9') { return false; } } return true; } console.log('should be true:'); console.log(validatePIN('1234')); console.log(validatePIN('0129')); console.log(validatePIN('123456')); console.log('should be false:'); console.log(validatePIN('12345')); console.log(validatePIN('a234')); console.log(validatePIN('123a')); console.log(validatePIN('-123')); console.log(validatePIN('1.23')); console.log(validatePIN('0x99')); console.log(validatePIN('0:29')); console.log(validatePIN('0/29'));

Ответ 2



Диапазон ASCII function validatePIN(pin, valid = true) { l = pin.length; if(l != 4 && l != 6) return false; Array.from(pin).forEach((s) => { s = s.charCodeAt(0); if(s > 57 || s < 48) valid = false; }); return valid; } console.log(validatePIN("1234")); console.log(validatePIN("0123")); console.log(validatePIN("123456")); console.log(validatePIN("12345")); console.log(validatePIN("a234")); console.log(validatePIN("123a")); console.log(validatePIN("-123")); console.log(validatePIN("1.23")); console.log(validatePIN("0x99")); console.log(validatePIN("0:29"));

Ответ 3



Или такой вариант: function validatePIN(pin) { if (isNaN(pin) || pin == 'null' || !isInteger(+pin)) { return false; } else if (pin.length == 4 || pin.length == 6) { return true; } return false; } function isInteger(num) { return (num ^ 0) === num; } console.log(validatePIN("123454")); //=== true console.log(validatePIN("1234")); //=== true console.log(validatePIN("a234")); //=== false console.log(validatePIN("a23445")); //=== false console.log(validatePIN('null')); //=== false console.log(validatePIN('1.23')); //=== false

Visual Studio 2015 добавляет лишний Resources1.Designer.cs

#c_sharp #visual_studio


Я редактирую содержимое ресурсов вручную в студии. После этого проект перестаёт собираться,
причина - Студия добавляет в проект новый файл Resources1.Designer.cs. Т.к. один файл
Resources.Designer.cs уже есть, студия ругается. Приходится после каждого редактирования
файла ресурсов удалять этот Resources1.Designer.cs, после чего проект нормально собирается.
Этот эффект проявлялся не сразу, не после создания проекта, а через некоторое время
(пару недель).
Кто знает, почему студия добавляет дополнительный файл Resources1.Designer.cs, и
как это дело пофиксить?


    


Ответы

Ответ 1



Проверьте, что содержится в файле проекта (.csproj) Если в теге LastGenOutput указано Resources1, например, так: ResXFileCodeGenerator Resources1.Designer.cs То уберите единицу: ResXFileCodeGenerator Resources.Designer.cs

Почему сравнения возвращают различные результаты?

#c_sharp #console #if


static bool Compare0()
{
    return new byte() == new byte();
}

static bool Compare1()
{
    return new byte[0] == new byte[0];
}

static void Main()
{
    Console.WriteLine(Compare0());
    Console.WriteLine(Compare1());

    Console.ReadKey();
}


Почему Compare0() возвращает True, а Compare1() - False?
    


Ответы

Ответ 1



Конструкция new byte() создает экземпляр типа byte, проинициализированный нулем. byte -- это структура, а следовательно, это значимый тип. По умолчанию все значимые типы сравниваются по значению. Поскольку два экземпляра проинициализированы одинаковым значением, Compare0() возвращает True. Конструкция new byte[0] создает пустой массив типа byte. Массив -- это ссылочный тип. По умолчанию экземпляры ссылочных типов равны, только если их ссылки равны, т.е. экземпляры указывают на один и тот же объект. Поскольку два экземпляра массива -- это два разных объекта в памяти, Compare1() возвращает False. Подробнее о значимых и ссылочных типах можно почитать в этом ответе.

Передача двух массивов в поток

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


Имеется 2 структуры (2 динамических массива), в каждой свой набор данных. Появилась
потребность перенести одну из функций в поток с помощью pthread_create (функцию change).

Не могу понять, как можно передать ссылки на эти 2 структуры в данную функцию (в
потоке), чтобы в ней я смог провести какие-нибудь операции у данных структур и с этими
изменениями я мог дальше работать в основной программе?

Спасибо.

Пример программы.

#include 
#include 
#include 
#include 
#include 
#include 

struct strc {
 char str[60];
 int uid;
 struct strc *prev;
};

struct param {
 struct stack *elma;
 struct stack *elmb;
};

struct stack *add(struct stack **base, char *line,int uid) {
 struct stack *element=(struct stack*)malloc(sizeof(struct stack));
 element->prev=*base;
 strcpy(element->data,line);
 element->uid=uid;
 return element;
}

int search(struct stack *base,char *str) {
 while (base!=NULL) {if (strcmp(base->data,str)==0) return base->uid; base=base->prev;}
 return 0;
}

void * change(void *arg) {
 struct param *data=arg;

 *data.elma=add(data.elma,"chips",5); 
 *data.elmb=add(data.elmb,"volvo",2); 
}

int main() {
 int uid;
 pthread_t thread;
 struct strc *elma=NULL;
 struct strc *elmb=NULL;
 struct param *arg;

 arg->elma=elma;
 arg->elmb=elmb;

 if (pthread_create(&thread, NULL, change, &arg) != 0) {return -1;}

 uid=search(elma,"chips");
 printf("%i",uid);
 uid=search(elmb,"volvo");
 printf("%i",uid);
}

    


Ответы

Ответ 1



Поправил Ваш пример до работоспособного состояния. #include #include #include #include #include #include #include struct stack { char data[60]; int uid; struct stack *prev; }; struct param { struct stack **elma; struct stack **elmb; }; struct stack *add(struct stack **base, char *line,int uid) { struct stack *element=(struct stack*)malloc(sizeof(struct stack)); element->prev=*base; strcpy(element->data,line); element->uid=uid; return element; } int search(struct stack *base,char *str) { while (base!=NULL) { if (strcmp(base->data,str)==0) return base->uid; base=base->prev; } return 0; } void * change(void *arg) { struct param *data=arg; *(data->elma) = add(data->elma, "chips", 5); *(data->elmb) = add(data->elmb, "volvo", 2); *(data->elma) = add(data->elma, "flips", 15); *(data->elmb) = add(data->elmb, "ford", 21); } int main() { int uid; pthread_t thread; struct stack *elma=NULL; struct stack *elmb=NULL; struct param arg; arg.elma=&elma; arg.elmb=&elmb; if (pthread_create(&thread, NULL, change, &arg) != 0) exit((puts("Can't create thread"), 1)); // тут делаете что-то полезное, \ пока не понадобятся данные из change() if (pthread_join(thread, 0)) exit((puts("Can't join"), 2)); uid=search(elma,"chips"); printf("chips: %i\n",uid); uid=search(elmb,"volvo"); printf("volvo: %i\n",uid); uid=search(elma,"flips"); printf("flips: %i\n",uid); uid=search(elmb,"bmw"); printf("bmw: %i\n",uid); } По сути, заменил передачу в change() указателей на "стеки" на передачу адресов этих указателей (структура param), поскольку в main Вы явно используете elma и elmb для обращения к search() и добавил вызов pthread_join для ожидания завершения заполнения "стеков" (естественно, добавил #include ). avp@wubu:hashcode$ gcc pt.c -lpthread && ./a.out chips: 5 volvo: 2 flips: 15 bmw: 0 avp@wubu:hashcode$

Ответ 2



Соберите указатели в одну структуру и передайте указатель на нее. Что-то типа struct param { struct strc * first; struct strc * second; }; struct param p; p.first = elma; p.second = elmb; и передавайте указатель на p. Примерно так.

Ответ 3



Не могу понять, как можно передать ссылки на эти 2 структуры в данную функцию (в потоке), Принципиальная разница между ПРОЦЕССОМ и ПОТОКОМ(нитью) заключается в том, что процессы работают в изолированных адресных пространствах, а все нити работают в одном(!) адресном пространстве. А это означает, что если Вы напишите вот так: struct data1 { . . . } struct data2 { . . . } void fun1(void *a) { . . . } void fun2(void *a) { . . . } То обе структуру данных будут видны в обоих функциях как глобально объявленные. И Вы можете запустить и ту и другую функцию как нити, не передавая в списках параметров вообще ничего. Существенно замечание: для того, что бы эти функции могли работать с ОБЩЕЙ структурой данных правильно, необходимо окружить эту работу защитными барьерами - мьютексами. Но это - отдельная тема.

Ответ 4



Используя предыдуший пример преобразуем чтобы было два массива typedef struct _data_s data_s; struct _data_s { int ready; int * first; int size_first; int * second; int size_second; }; static gpointer thread_fun(gpointer d) { int rc; data_s * data = (data_s*)d; int * first = data->first; int * second = data->second; int * local_first = g_slice_alloc0(sizeof(int)*data->size_first,); int * local_second = g_slice_alloc0(sizeof(int)*data->size_second);; for(;;){ /*чтение данных*/ rc = g_mutex_trylock(&mutex); if(rc){ rc = data->ready; if(rc){ memmove(local_first,first,data->size_first); memmove(local_second,second,data->size_second); data->ready = FALSE; g_mutex_unlock(&mutex); } else{ g_mutex_unlock(&mutex); g_usleep(10000); continue; } } else{ g_usleep(10000); continue; } /*обработка данных*/ .... /*запись данных*/ g_mutex_lock(&mutex); memmove(first,local_first,data->size_first); memmove(second,local_second,data->size_second); g_mutex_unlock(&mutex); /*если требуется накопление данных*/ g_usleep(TIMEOUT); } g_slice_free1(data->size_first,local_first); g_slice_free1(data->size_second,local_second); return NULL; int main(int argc,char * argv[]) { GThread * thread; data_s data; data.ready = FALSE; data.size_first = 10; data.first = g_slice_alloc0(sizeof(int)*data.size_first); data.size_second = 10; data.second = g_slice_alloc0(sizeof(int)*data.size_second); g_mutex_init(&mutex); thread = g_thread_new("data",thread_fun,&data); for(;;){ g_mutex_lock(&mutex); read(fd1,data.first,data.size_first); read(fd2,data.second,data.size_second); data.ready = TRUE; g_mutex_unlock(&mutex); } g_slice_free1(data.size_first,data.first); g_slice_free1(data.size_second,data.second); return 0; }