Шаблоны могут привыкнуть к переменным структуры доступа по имени?

Вот рабочее испытание для одного подхода:

from flask import Flask, render_template_string, session, request

import pandas as pd
app = Flask(__name__)

template = """
<!doctype html>
<input type="text" value="" name="my_filter" id="my_filter">

<div id="results">{{ data|safe }}</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script type="text/javascript">
   $('#my_filter').keyup(function() {
       if ($(this).val().length >= 1) {
           var requested_code = document.getElementById('my_filter').value;

           $.ajax({
               type: 'POST',
               data: JSON.stringify({
                   'requested_code': requested_code
               }),
               contentType: 'application/json; charset=utf-8',
               url: "{{ url_for('filter_html') }}",
               success: function(resp) {
                   $("#results").html(resp);
               }
           });

       }
});
</script>
</html>
"""

@app.route("/")
def table():
    df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
    session['df'] = df.values.tolist()
    return render_template_string(template, data=df.to_html(index=False))


@app.route('/filter', methods=['GET', 'POST'])
def filter_html():
    df = pd.DataFrame(session['df'], columns=['a', 'b'])
    df = df[df['a'] == int(request.json.get('requested_code'))]
    return df.to_html(index=False)


if __name__ == '__main__':
    app.secret_key = 'hello'
    app.run(debug=True)

По сути, добавьте функцию JQuery в блок input, который ищет события keyup. Однако они должны инициировать запрос AJAX к конечной точке URL во Flask, которая затем может обновить div "results". Могут быть более чистые способы сериализации данных, которые будут сохранены в сеансе; это просто для иллюстрации подхода.

По умолчанию session в Flask довольно мало. Если вы попытаетесь сохранить объект, который слишком велик, чтобы уместиться, это не приведет к ошибке, проблема просто игнорируется. Вы захотите использовать flask-session для хранения данных DF; в настоящее время вы отправляете все это в браузер, поэтому я предполагаю, что он не слишком большой.

Для тех, кто менее знаком с Flask, но работает с Pandas: вы можете запустить этот код и затем перейти к 127.0.0.1:5000 в вашем браузере. Числа 1, 2 или 3 действительны для ввода в поле поиска для взаимодействия с df, все остальное приводит к пустому df.

17
задан Steephen 19 May 2015 в 20:06
поделиться

8 ответов

#include <iostream>
#include <ostream>
#include <string>

struct my_struct
{
    int a;
    std::string b;
};

template <typename TObject, typename TMember, typename TValue>
void set( TObject* object, TMember member, TValue value )
{
    ( *object ).*member = value;
}

class undo_token {};

template <class TValue>
class undo_member : public undo_token
{
    TValue new_value_;
    typedef TValue my_struct::* TMember;
    TMember member_;

public:
    undo_member(TMember member, TValue new_value):
        new_value_( new_value ),
        member_( member )
    {}

    void undo(my_struct *s) 
    { 
        set( s, member_, new_value_ );
    }
};    

int main()
{
    my_struct s;

    set( &s, &my_struct::a, 2 );
    set( &s, &my_struct::b, "hello" );

    std::cout << "s.a = " << s.a << std::endl;
    std::cout << "s.b = " << s.b << std::endl;

    undo_member<int> um1( &my_struct::a, 4 );
    um1.undo( &s );

    std::cout << "s.a = " << s.a << std::endl;

    undo_member<std::string> um2( &my_struct::b, "goodbye" );
    um2.undo( &s );

    std::cout << "s.b = " << s.b << std::endl;

    return 0;
}
19
ответ дан 30 November 2019 в 10:02
поделиться

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

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

, Например, член целого числа типа, которое хранит возраст человека и другого для хранения их фамилии:

struct age { typedef int value_type; };
struct last_name { typedef std::string value_type; };

Тогда Вам нужно что-то как map, который делает поиск во время компиляции. Позвольте нам, назвал его ctmap. Давайте окажем ему поддержку максимум 8 участникам. Во-первых нам нужен заполнитель для представления отсутствия поля:

struct none { struct value_type {}; };

Тогда мы можем передать - объявляют форму [1 111]:

template <
    class T0 = none, class T1 = none,
    class T2 = none, class T3 = none,
    class T4 = none, class T5 = none,
    class T6 = none, class T7 = none
    >
struct ctmap;

Мы тогда специализируем это для случая, где нет никаких полей:

template <>
struct ctmap<
    none, none, none, none,
    none, none, none, none
    >
{
    void operator[](const int &) {};
};

причина этого прибудется ясная (возможно) через мгновение. Наконец, определение для всех других случаев:

template <
    class T0, class T1, class T2, class T3,
    class T4, class T5, class T6, class T7
    >
    struct ctmap : public ctmap<T1, T2, T3, T4, T5, T6, T7, none>
    {
        typedef ctmap<T1, T2, T3, T4, T5, T6, T7, none> base_type;

        using base_type::operator[];
        typename T0::value_type storage;

        typename T0::value_type &operator[](const T0 &c)
        { return storage; }
};

, Что продолжение ада здесь? Если Вы помещаете:

ctmap<last_name, age> person;

C++ создаст тип для [1 112] путем рекурсивного расширения шаблонов, потому что ctmap наследовался себе , и мы обеспечиваем устройство хранения данных для первого поля и затем отбрасываем его, когда мы наследовались. Это все прибывает во внезапную остановку, когда больше нет полей, потому что специализация для все-none умирает.

, Таким образом, мы можем сказать:

person[last_name()] = "Smith";
person[age()] = 104;

Это похоже на поиск в map, но во время компиляции, с помощью полевого класса идентификатора в качестве ключа.

Это означает, что мы можем также сделать это:

template <class TMember>
void print_member(ctmap<last_name, age> &person)
{
    std::cout << person[TMember()] << std::endl;
}

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

print_member<age>(person);

Так да, можно записать вещь, которая немного похожа struct, немного как время компиляции map.

35
ответ дан 30 November 2019 в 10:02
поделиться

Я не уверен, почему Вы не можете использовать указатель, таким образом, я не знаю, является ли это соответствующим, но взгляните на C++: Указатель на элемент данных класса , который описывает способ, которым можно передать указатель на элемент данных структуры/класса, которая не указывает непосредственно участнику, , но позже связывается с указателем структуры/класса . (акцент, добавленный после редактирования плаката, объясняющего, почему указатель не может использоваться)

Этот способ, которым Вы не передаете указатель на участника - вместо этого, он больше похож на смещение в объекте.

4
ответ дан 30 November 2019 в 10:02
поделиться

Ответ Mykola Golubyev хорош, но он может быть улучшен немного при помощи того, что указатели на участников могут использоваться в качестве шаблонных параметров нетипа:

#include <iostream>
#include <ostream>
#include <string>

struct my_struct
{
    int a;
    std::string b;
};

template <typename TObject, typename TMember, typename TValue>
void set( TObject* object, TMember member, TValue value )
{
    ( *object ).*member = value;
}

class undo_token {};

template <class TValue, TValue my_struct::* Member>
class undo_member : public undo_token
{
        // No longer need to store the pointer-to-member
        TValue new_value_;

public:
        undo_member(TValue new_value):
                new_value_(new_value)
        {}

        void undo(my_struct *s) 
        { 
                set( s, Member, new_value_ );
        }
};    

int main()
{
    my_struct s;

    set( &s, &my_struct::a, 2 );
    set( &s, &my_struct::b, "hello" );

    std::cout << "s.a = " << s.a << std::endl;
    std::cout << "s.b = " << s.b << std::endl;

    undo_member<int, &my_struct::a> um1( 4 );
    um1.undo( &s );

    std::cout << "s.a = " << s.a << std::endl;

    undo_member<std::string, &my_struct::b> um2( "goodbye" );
    um2.undo( &s );

    std::cout << "s.b = " << s.b << std::endl;

    return 0;
}

Это сбривает стоимость указателя на участника от каждого экземпляра undo_member.

6
ответ дан 30 November 2019 в 10:02
поделиться

Из того, что Вы описали, я предполагаю, что у Вас нет способа переопределить структуру.

, Если бы Вы сделали, я предложил бы, чтобы Вы использовали Повышение. Fusion для описания структуры с названными шаблоном полями. См. ассоциативные кортежи для получения дополнительной информации об этом. Оба вида структур могли бы на самом деле быть совместимыми (та же организация в памяти), но я вполне уверен нет никакого способа получить такую гарантию из стандарта.

, Если бы Вы не делаете, можно создать дополнение к структуре, которая предоставила бы Вам доступ к полям тот же способ, которым делают ассоциативные кортежи. Но это может быть немного словесным.

РЕДАКТИРОВАНИЕ

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

2
ответ дан 30 November 2019 в 10:02
поделиться

Вы не можете использовать шаблоны для решения этого, но почему использование структура в te первом месте? Это походит на идеальное использование для станд.:: карта, которая отобразила бы имена к значениям.

2
ответ дан 30 November 2019 в 10:02
поделиться

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

Вы правы в своем разделе EDIT. Это вопрос дизайна.

1
ответ дан 30 November 2019 в 10:02
поделиться

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

114-секундный хит на Google для "шаблонов отражения C++" был статьей на" Отражательная поддержка посредством шаблонного метапрограммирования ". Это должно запустить Вас. Даже если это не совсем, что Вы ищете, это может показать Вам способ решить Вашу проблему.

3
ответ дан 30 November 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: