问:
deserialization issue after changing namespace to customise tag names for boost xml
I have made the below changes to have customised names for tags.
And the below code changes worked successfully and i could create a xml doc with customised names.

```<code>namespace boost { namespace serialization {
    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const , Myclass::Pgroups>& p, unsigned) {
            ar & make_nvp("assetid", p.first) & make_nvp("assetdata", p.second);
        }
} }

namespace boost { namespace serialization {
    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const , values>& p, unsigned) {
            ar & make_nvp("hacc_groupid", p.first) & make_nvp("hacc_groupdata", p.second);
        }
} }
</code>```

But this seems to be a problem  deserialising the xml to the object, i get boost error

```<code> template<class Archive, class Object>
   std::string serialise_to_string(const char* tag,Object & obj)
   {
     std::ostringstream os (std::ios::binary);
     Archive arch ( os );
     arch << boost::serialization::make_nvp(tag,obj);
     return os.str();
   }
   template<class Archive , class Object>
   void deserialise_to_obj( std::string const  &s1,Object &outObj)
   {
      std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
      Archive arch (is);
      arch >> boost::serialization::make_nvp("tag",outObj);
   };
</code>```

Without boost namespace customisation the serialisation and deserialisation are perfectly working  , but with change in boost namespace for having customised tag names , the deserialisation has issue .

Error with the above code , i.e  with const in namespace  argvoid serialize(Ar& ar,std::pair<int const , values>& p, unsigned)

```<code>In file included from main.cpp:1:
In file included from /usr/local/include/boost/archive/binary_oarchive.hpp:21:
In file included from /usr/local/include/boost/archive/binary_oarchive_impl.hpp:22:
In file included from /usr/local/include/boost/archive/basic_binary_oarchive.hpp:33:
In file included from /usr/local/include/boost/archive/detail/common_oarchive.hpp:22:
In file included from /usr/local/include/boost/archive/detail/interface_oarchive.hpp:23:
In file included from /usr/local/include/boost/archive/detail/oserializer.hpp:68:
/usr/local/include/boost/archive/detail/check.hpp:162:5: error: static_assert failed "typex::value"
    BOOST_STATIC_ASSERT(typex::value);
    ^                   ~~~~~~~~~~~~
/usr/local/include/boost/static_assert.hpp:70:41: note: expanded from macro 'BOOST_STATIC_ASSERT'
#     define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__)
                                        ^             ~~~~~~~~~~~
/usr/local/include/boost/archive/detail/iserializer.hpp:603:13: note: in instantiation of function template specialization 'boost::archive::detail::check_const_loading<const int>' requested here
    detail::check_const_loading< T >();
            ^
/usr/local/include/boost/archive/detail/common_iarchive.hpp:66:18: note: in instantiation of function template specialization 'boost::archive::load<boost::archive::xml_iarchive, const int>' requested here
        archive::load(* this->This(), t);
                 ^
/usr/local/include/boost/archive/basic_xml_iarchive.hpp:78:39: note: in instantiation of function template specialization 'boost::archive::detail::common_iarchive<boost::archive::xml_iarchive>::load_override<const int>' requested here
        this->detail_common_iarchive::load_override(t.value());
                                      ^
/usr/local/include/boost/archive/xml_iarchive.hpp:95:38: note: in instantiation of function template specialization 'boost::archive::basic_xml_iarchive<boost::archive::xml_iarchive>::load_override<const int>' requested here
        basic_xml_iarchive<Archive>::load_override(t);
                                     ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:68:23: note: in instantiation of function template specialization 'boost::archive::xml_iarchive_impl<boost::archive::xml_iarchive>::load_override<const boost::serialization::nvp<const int> >' requested here
        this->This()->load_override(t);
                      ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:75:32: note: (skipping 45 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
        return *(this->This()) >> t;
                               ^
/usr/local/include/boost/archive/basic_xml_iarchive.hpp:78:39: note: in instantiation of function template specialization 'boost::archive::detail::common_iarchive<boost::archive::xml_iarchive>::load_override<Myclass>' requested here
        this->detail_common_iarchive::load_override(t.value());
                                      ^
/usr/local/include/boost/archive/xml_iarchive.hpp:95:38: note: in instantiation of function template specialization 'boost::archive::basic_xml_iarchive<boost::archive::xml_iarchive>::load_override<Myclass>' requested here
        basic_xml_iarchive<Archive>::load_override(t);
                                     ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:68:23: note: in instantiation of function template specialization 'boost::archive::xml_iarchive_impl<boost::archive::xml_iarchive>::load_override<const boost::serialization::nvp<Myclass> >' requested here
        this->This()->load_override(t);
</code>```

If const-ness is removed from the boost namespace , deserialise_to_obj and serialise_to_string functions ,the code compiles and runs without any issue but doesn't customise the tag name

Hope my information is clear,
Iam stuck at an issue where iam really not sure whether the deserialisation to object can smoothly happen with customised tag names.
Please advice me what has to be done

Sample code foe serialisation and deserialisation with custom tag names  live at coliru

sample working code without deserialzation and custom tag names
live at coliru

Thanks
Tejas

答:
The cinch is in the const-ness of std::pair<>::first for std::map::value_type.

This is one of the very few cases where using const_cast makes sense:

```<code>namespace boost { namespace serialization {
    template<class Ar>
        inline void serialize(Ar & ar, std::pair<int const, values> & p, unsigned) {
            ar & make_nvp("assetid", const_cast<int&>(p.first)) & make_nvp("assetdata", p.second);
        }

    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const, Myclass::Pgroups>& p, unsigned) {
            ar & make_nvp("hacc_groupid", const_cast<int&>(p.first)) & make_nvp("hacc_groupdata", p.second);
        }
} }
</code>```

Incidentally, this is also what Boost Serialization does: http://www.boost.org/doc/libs/1_63_0/boost/serialization/utility.hpp

Full Working Demo

Updated: Also overrides the the item node name now

Live On Coliru

```<code>#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>

#include <map>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_member.hpp>

using boost::serialization::make_nvp;

namespace MyDomain { // demonstrate ADL for serialize
    struct values
    {
        std::string name;
        std::string sex;
        values() : name("dummy"), sex("dummy") {};

        template<class Archive>
            void serialize(Archive & ar, const unsigned int /*version*/) {
                ar & make_nvp("name", name);
                ar & make_nvp("sex", sex);
            }
    };

    struct Myclass {
        Myclass() { }

        template<class Archive>
            void serialize(Archive & ar, const unsigned int /*version*/)  {
                ar & make_nvp("etoto", e_group);
                ar & make_nvp("ptoto", p_group);
            }

        typedef std::map<int,values> groups;
        typedef std::map<int,groups> Pgroups;

        groups  e_group;
        Pgroups p_group;
    };

    #define CUSTOM_MAP_SERIALIZE(Map, keyname, valuename) \
    template<class Ar> inline void serialize(Ar & ar, Map::value_type& p, unsigned) { \
            ar & make_nvp(keyname, const_cast<int&>(p.first)) & make_nvp(valuename, p.second); \
        }

    CUSTOM_MAP_SERIALIZE(Myclass::groups, "assetid", "assetdata")
    CUSTOM_MAP_SERIALIZE(Myclass::Pgroups, "hacc_groupid", "hacc_groupdata")
}

namespace boost { namespace serialization {

    #define OVERRIDE_NVP(T, name) \
       template <> inline const nvp<T> make_nvp(const char *, T &t) { return nvp<T>(name, t); } \
       template <> inline const nvp<T const> make_nvp(const char *, T const &t) { return nvp<T const>(name, t); }

    OVERRIDE_NVP(MyDomain::Myclass::groups::value_type,  "group_item")
    OVERRIDE_NVP(MyDomain::Myclass::Pgroups::value_type, "Pgroup_item")

    #undef OVERRIDE_NVP
} }

template<class Archive, class Object>
std::string serialise_to_string(Object const& assetlist)
{
    auto os = std::ostringstream(std::ios::binary);
    Archive arch { os, boost::archive::no_header };
    arch << make_nvp("Main", assetlist);
    return os.str();
}

template<class Archive , class Object>
void deserialise_to_obj(std::string const &s1,Object &outObj)
{
    std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
    Archive arch { is, boost::archive::no_header };
    arch >> make_nvp("Main", outObj);
}

MyDomain::Myclass create_data()
{
    MyDomain::Myclass object;
    MyDomain::values val1;
    object.e_group.insert( std::make_pair(1,val1) ) ;
    object.e_group.insert( std::make_pair(2,val1) ) ;
    object.p_group.insert( std::make_pair(1,object.e_group) ) ;
    object.p_group.insert( std::make_pair(2,object.e_group) ) ;
    return object;
}

int main() {
    {
        MyDomain::Myclass obj = create_data() ;

        std::string s2 = serialise_to_string<boost::archive::xml_oarchive>(obj);

        //Save xml to a file
        {
            std::ofstream ofs("output1.xml");
            ofs << s2 << std::endl << std::endl;
            ofs.close();
        }

    }

    std::string content;
    {
        std::ifstream ifs("output1.xml");
        content.assign(std::istreambuf_iterator<char>(ifs), {});
        ifs.close();
    }
    {
        MyDomain::Myclass outObj;
        deserialise_to_obj<boost::archive::xml_iarchive>(content,outObj);
        //Print the object
        for(auto &i:outObj.p_group){
            std::cout<<"\n"<<i.first<<"\n";
            for(auto &j:i.second){
                std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n";
            }
        }
    }
}
</code>```

Prints

```<code>1
    1   dummy   dummy
    2   dummy   dummy

2
    1   dummy   dummy
    2   dummy   dummy
</code>```

With output1.xml

    <etoto class_id="1" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <group_item class_id="2" tracking_level="0" version="0">
            <assetid>1</assetid>
            <assetdata class_id="3" tracking_level="0" version="0">
                <name>dummy</name>
                <sex>dummy</sex>
            </assetdata>
        </group_item>
        <group_item>
            <assetid>2</assetid>
            <assetdata>
                <name>dummy</name>
                <sex>dummy</sex>
            </assetdata>
        </group_item>
    </etoto>
    <ptoto class_id="4" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <Pgroup_item class_id="5" tracking_level="0" version="0">
            <hacc_groupid>1</hacc_groupid>
            <hacc_groupdata>
                <count>2</count>
                <item_version>0</item_version>
                <group_item>
                    <assetid>1</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
                <group_item>
                    <assetid>2</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
            </hacc_groupdata>
        </Pgroup_item>
        <Pgroup_item>
            <hacc_groupid>2</hacc_groupid>
            <hacc_groupdata>
                <count>2</count>
                <item_version>0</item_version>
                <group_item>
                    <assetid>1</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
                <group_item>
                    <assetid>2</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
            </hacc_groupdata>
        </Pgroup_item>
    </ptoto>

```

Body:
I have made the below changes to have customised names for tags.
And the below code changes worked successfully and i could create a xml doc with customised names.

namespace boost { namespace serialization {
    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const , Myclass::Pgroups>& p, unsigned) {
            ar & make_nvp("assetid", p.first) & make_nvp("assetdata", p.second);
        }
} }

namespace boost { namespace serialization {
    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const , values>& p, unsigned) {
            ar & make_nvp("hacc_groupid", p.first) & make_nvp("hacc_groupdata", p.second);
        }
} }

But this seems to be a problem  deserialising the xml to the object, i get boost error

 template<class Archive, class Object>
   std::string serialise_to_string(const char* tag,Object & obj)
   {
     std::ostringstream os (std::ios::binary);
     Archive arch ( os );
     arch << boost::serialization::make_nvp(tag,obj);
     return os.str();
   }
   template<class Archive , class Object>
   void deserialise_to_obj( std::string const  &s1,Object &outObj)
   {
      std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
      Archive arch (is);
      arch >> boost::serialization::make_nvp("tag",outObj);
   };

Without boost namespace customisation the serialisation and deserialisation are perfectly working  , but with change in boost namespace for having customised tag names , the deserialisation has issue .

Error with the above code , i.e  with const in namespace  argvoid serialize(Ar& ar,std::pair<int const , values>& p, unsigned)

In file included from main.cpp:1:
In file included from /usr/local/include/boost/archive/binary_oarchive.hpp:21:
In file included from /usr/local/include/boost/archive/binary_oarchive_impl.hpp:22:
In file included from /usr/local/include/boost/archive/basic_binary_oarchive.hpp:33:
In file included from /usr/local/include/boost/archive/detail/common_oarchive.hpp:22:
In file included from /usr/local/include/boost/archive/detail/interface_oarchive.hpp:23:
In file included from /usr/local/include/boost/archive/detail/oserializer.hpp:68:
/usr/local/include/boost/archive/detail/check.hpp:162:5: error: static_assert failed "typex::value"
    BOOST_STATIC_ASSERT(typex::value);
    ^                   ~~~~~~~~~~~~
/usr/local/include/boost/static_assert.hpp:70:41: note: expanded from macro 'BOOST_STATIC_ASSERT'
#     define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__)
                                        ^             ~~~~~~~~~~~
/usr/local/include/boost/archive/detail/iserializer.hpp:603:13: note: in instantiation of function template specialization 'boost::archive::detail::check_const_loading<const int>' requested here
    detail::check_const_loading< T >();
            ^
/usr/local/include/boost/archive/detail/common_iarchive.hpp:66:18: note: in instantiation of function template specialization 'boost::archive::load<boost::archive::xml_iarchive, const int>' requested here
        archive::load(* this->This(), t);
                 ^
/usr/local/include/boost/archive/basic_xml_iarchive.hpp:78:39: note: in instantiation of function template specialization 'boost::archive::detail::common_iarchive<boost::archive::xml_iarchive>::load_override<const int>' requested here
        this->detail_common_iarchive::load_override(t.value());
                                      ^
/usr/local/include/boost/archive/xml_iarchive.hpp:95:38: note: in instantiation of function template specialization 'boost::archive::basic_xml_iarchive<boost::archive::xml_iarchive>::load_override<const int>' requested here
        basic_xml_iarchive<Archive>::load_override(t);
                                     ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:68:23: note: in instantiation of function template specialization 'boost::archive::xml_iarchive_impl<boost::archive::xml_iarchive>::load_override<const boost::serialization::nvp<const int> >' requested here
        this->This()->load_override(t);
                      ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:75:32: note: (skipping 45 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
        return *(this->This()) >> t;
                               ^
/usr/local/include/boost/archive/basic_xml_iarchive.hpp:78:39: note: in instantiation of function template specialization 'boost::archive::detail::common_iarchive<boost::archive::xml_iarchive>::load_override<Myclass>' requested here
        this->detail_common_iarchive::load_override(t.value());
                                      ^
/usr/local/include/boost/archive/xml_iarchive.hpp:95:38: note: in instantiation of function template specialization 'boost::archive::basic_xml_iarchive<boost::archive::xml_iarchive>::load_override<Myclass>' requested here
        basic_xml_iarchive<Archive>::load_override(t);
                                     ^
/usr/local/include/boost/archive/detail/interface_iarchive.hpp:68:23: note: in instantiation of function template specialization 'boost::archive::xml_iarchive_impl<boost::archive::xml_iarchive>::load_override<const boost::serialization::nvp<Myclass> >' requested here
        this->This()->load_override(t);

If const-ness is removed from the boost namespace , deserialise_to_obj and serialise_to_string functions ,the code compiles and runs without any issue but doesn't customise the tag name

Hope my information is clear,
Iam stuck at an issue where iam really not sure whether the deserialisation to object can smoothly happen with customised tag names.
Please advice me what has to be done

Sample code foe serialisation and deserialisation with custom tag names  live at coliru

sample working code without deserialzation and custom tag names
live at coliru

Thanks
Tejas

Body:
The cinch is in the const-ness of std::pair<>::first for std::map::value_type.

This is one of the very few cases where using const_cast makes sense:

namespace boost { namespace serialization {
    template<class Ar>
        inline void serialize(Ar & ar, std::pair<int const, values> & p, unsigned) {
            ar & make_nvp("assetid", const_cast<int&>(p.first)) & make_nvp("assetdata", p.second);
        }

    template <typename Ar>
        void serialize(Ar& ar,std::pair<int const, Myclass::Pgroups>& p, unsigned) {
            ar & make_nvp("hacc_groupid", const_cast<int&>(p.first)) & make_nvp("hacc_groupdata", p.second);
        }
} }

Incidentally, this is also what Boost Serialization does: http://www.boost.org/doc/libs/1_63_0/boost/serialization/utility.hpp

Full Working Demo

Updated: Also overrides the the item node name now

Live On Coliru

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>

#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/nvp.hpp>
#include <iostream>
#include <string>
#include <iomanip>
#include <sstream>
#include <fstream>

#include <map>
#include <boost/serialization/map.hpp>
#include <boost/serialization/split_member.hpp>

using boost::serialization::make_nvp;

namespace MyDomain { // demonstrate ADL for serialize
    struct values
    {
        std::string name;
        std::string sex;
        values() : name("dummy"), sex("dummy") {};

        template<class Archive>
            void serialize(Archive & ar, const unsigned int /*version*/) {
                ar & make_nvp("name", name);
                ar & make_nvp("sex", sex);
            }
    };

    struct Myclass {
        Myclass() { }

        template<class Archive>
            void serialize(Archive & ar, const unsigned int /*version*/)  {
                ar & make_nvp("etoto", e_group);
                ar & make_nvp("ptoto", p_group);
            }

        typedef std::map<int,values> groups;
        typedef std::map<int,groups> Pgroups;

        groups  e_group;
        Pgroups p_group;
    };

    #define CUSTOM_MAP_SERIALIZE(Map, keyname, valuename) \
    template<class Ar> inline void serialize(Ar & ar, Map::value_type& p, unsigned) { \
            ar & make_nvp(keyname, const_cast<int&>(p.first)) & make_nvp(valuename, p.second); \
        }

    CUSTOM_MAP_SERIALIZE(Myclass::groups, "assetid", "assetdata")
    CUSTOM_MAP_SERIALIZE(Myclass::Pgroups, "hacc_groupid", "hacc_groupdata")
}

namespace boost { namespace serialization {

    #define OVERRIDE_NVP(T, name) \
       template <> inline const nvp<T> make_nvp(const char *, T &t) { return nvp<T>(name, t); } \
       template <> inline const nvp<T const> make_nvp(const char *, T const &t) { return nvp<T const>(name, t); }

    OVERRIDE_NVP(MyDomain::Myclass::groups::value_type,  "group_item")
    OVERRIDE_NVP(MyDomain::Myclass::Pgroups::value_type, "Pgroup_item")

    #undef OVERRIDE_NVP
} }

template<class Archive, class Object>
std::string serialise_to_string(Object const& assetlist)
{
    auto os = std::ostringstream(std::ios::binary);
    Archive arch { os, boost::archive::no_header };
    arch << make_nvp("Main", assetlist);
    return os.str();
}

template<class Archive , class Object>
void deserialise_to_obj(std::string const &s1,Object &outObj)
{
    std::stringstream is( s1, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
    Archive arch { is, boost::archive::no_header };
    arch >> make_nvp("Main", outObj);
}

MyDomain::Myclass create_data()
{
    MyDomain::Myclass object;
    MyDomain::values val1;
    object.e_group.insert( std::make_pair(1,val1) ) ;
    object.e_group.insert( std::make_pair(2,val1) ) ;
    object.p_group.insert( std::make_pair(1,object.e_group) ) ;
    object.p_group.insert( std::make_pair(2,object.e_group) ) ;
    return object;
}

int main() {
    {
        MyDomain::Myclass obj = create_data() ;

        std::string s2 = serialise_to_string<boost::archive::xml_oarchive>(obj);

        //Save xml to a file
        {
            std::ofstream ofs("output1.xml");
            ofs << s2 << std::endl << std::endl;
            ofs.close();
        }

    }

    std::string content;
    {
        std::ifstream ifs("output1.xml");
        content.assign(std::istreambuf_iterator<char>(ifs), {});
        ifs.close();
    }
    {
        MyDomain::Myclass outObj;
        deserialise_to_obj<boost::archive::xml_iarchive>(content,outObj);
        //Print the object
        for(auto &i:outObj.p_group){
            std::cout<<"\n"<<i.first<<"\n";
            for(auto &j:i.second){
                std::cout<<"\t"<<j.first<<"\t"<<j.second.name<<"\t"<<j.second.sex<<"\n";
            }
        }
    }
}

Prints

1
    1   dummy   dummy
    2   dummy   dummy

2
    1   dummy   dummy
    2   dummy   dummy

With output1.xml

<Main class_id="0" tracking_level="0" version="0">
    <etoto class_id="1" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <group_item class_id="2" tracking_level="0" version="0">
            <assetid>1</assetid>
            <assetdata class_id="3" tracking_level="0" version="0">
                <name>dummy</name>
                <sex>dummy</sex>
            </assetdata>
        </group_item>
        <group_item>
            <assetid>2</assetid>
            <assetdata>
                <name>dummy</name>
                <sex>dummy</sex>
            </assetdata>
        </group_item>
    </etoto>
    <ptoto class_id="4" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <Pgroup_item class_id="5" tracking_level="0" version="0">
            <hacc_groupid>1</hacc_groupid>
            <hacc_groupdata>
                <count>2</count>
                <item_version>0</item_version>
                <group_item>
                    <assetid>1</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
                <group_item>
                    <assetid>2</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
            </hacc_groupdata>
        </Pgroup_item>
        <Pgroup_item>
            <hacc_groupid>2</hacc_groupid>
            <hacc_groupdata>
                <count>2</count>
                <item_version>0</item_version>
                <group_item>
                    <assetid>1</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
                <group_item>
                    <assetid>2</assetid>
                    <assetdata>
                        <name>dummy</name>
                        <sex>dummy</sex>
                    </assetdata>
                </group_item>
            </hacc_groupdata>
        </Pgroup_item>
    </ptoto>
</Main>


来源: stackexchange

问:
ActiveRecord: Order table based on the average of an association's column
I am building a system for job seekers to track jobs their interested in using Rails. I want to rank companies based on the user's level of interest in the company as determined by averaging the user-declared 'level of interest' in each job posted by the company. So, for example, Wal Mart might post 3 jobs, and the user would submit their level of interest for each of those jobs, and we'd calculate the overall interest in Wal Mart by averaging those 3 levels of interest. There will be several companies with several jobs.

My database has 2 tables: Companies and Jobs, where a company has many jobs and a job has one company. A job also has a 'level_of_interest' attribute which should be used to calculate the user's overall interest in a company.

Is there a way to do this using just ActiveRecord methods? My current solution is:

```<code>Job.group('company_id').average(:level_of_interest)
</code>```

And then using Ruby to pull the companies out of the resulting hash, but I think there's probably a way to do it purely with ActiveRecord.

DB is PG, fwiw.

答:
Something like this should work:</p>

```<code>Company.select('companies.id, avg(jobs.level_of_interest)')
       .joins(:jobs)
       .group('companies.id')
       .order('avg(jobs.level_of_interest) desc')
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am building a system for job seekers to track jobs their interested in using Rails. I want to rank companies based on the user's level of interest in the company as determined by averaging the user-declared 'level of interest' in each job posted by the company. So, for example, Wal Mart might post 3 jobs, and the user would submit their level of interest for each of those jobs, and we'd calculate the overall interest in Wal Mart by averaging those 3 levels of interest. There will be several companies with several jobs.

My database has 2 tables: Companies and Jobs, where a company has many jobs and a job has one company. A job also has a 'level_of_interest' attribute which should be used to calculate the user's overall interest in a company.

Is there a way to do this using just ActiveRecord methods? My current solution is:

Job.group('company_id').average(:level_of_interest)

And then using Ruby to pull the companies out of the resulting hash, but I think there's probably a way to do it purely with ActiveRecord.

DB is PG, fwiw.

Body:
Something like this should work:

Company.select('companies.id, avg(jobs.level_of_interest)')
       .joins(:jobs)
       .group('companies.id')
       .order('avg(jobs.level_of_interest) desc')


问:
How can I retrieve messages logged with os_log from iPad/iPhone?
I am using the new Unified Logging API in Swift.

So I create a logger and use it as below:

```<code>let testLogger = OSLog(subsystem: "my.subsystem", category: "test")
os_log("just a test: %@", log: testLogger, type: .error, "error")
</code>```

How can I retrieve the logged message if the iOS device is disconnected from the Mac?

I know that the new Console application shows messages logged when the device is connected to the Mac. However, I want to retrieve a message that was logged when the device was disconnected from the computer. How can I achieve that?

Thank you.

答:
The only way I have been able to uncover is to trigger a sysdiagnose on the iOS device, then connect it to a computer and let it sync with iTunes, then gather the logs from the filesystem.

To trigger a sysdiagnose on an iOS device you need to press the volume up, volume down and power buttons at the same time. Then wait for it to finish. Apple says "10 minutes". Then connect to a computer and sync with iTunes.

The logs are on macOS here:

```<code>~/Library/Logs/CrashReporter/MobileDevice/[Your_Device_Name]/DiagnosticLogs/sysdiagnose
</code>```

On Windows, I am not sure.

More details in Apple sysdiagnose intructions

Body:
I am using the new Unified Logging API in Swift.

So I create a logger and use it as below:

let testLogger = OSLog(subsystem: "my.subsystem", category: "test")
os_log("just a test: %@", log: testLogger, type: .error, "error")

How can I retrieve the logged message if the iOS device is disconnected from the Mac?

I know that the new Console application shows messages logged when the device is connected to the Mac. However, I want to retrieve a message that was logged when the device was disconnected from the computer. How can I achieve that?

Thank you.

Body:
The only way I have been able to uncover is to trigger a sysdiagnose on the iOS device, then connect it to a computer and let it sync with iTunes, then gather the logs from the filesystem.

To trigger a sysdiagnose on an iOS device you need to press the volume up, volume down and power buttons at the same time. Then wait for it to finish. Apple says "10 minutes". Then connect to a computer and sync with iTunes.

The logs are on macOS here:

~/Library/Logs/CrashReporter/MobileDevice/[Your_Device_Name]/DiagnosticLogs/sysdiagnose

On Windows, I am not sure.

More details in Apple sysdiagnose intructions


问:
How does this for loop on consecutive integers work?
This seems like an embarrassingly easy concept but I can't understand why this for loop is working the way it is. The question is simply asking "Given a binary array, find the maximum number of consecutive 1s in this array."

```<code>def main(nums):
 count = 0
 for num in nums:
   if num == 1:
    count+=1
   else:
    count = 0
main([1,1,0,1,1,1,0,0,1,1,1,1,1])
</code>```

My question is, why does this for loop work? I expected the loop to print out the total count of 1's.

答:
The difference is that once it sees a zero, it sets the value of count back down to zero, saying that it's seen 0 consecutive ones. This code actually doesn't work—it only gets lucky on this input because the longest sequence is at the very end of the list.

A better practice would be to store both the lengths of the current_group of ones and the highest_total count.

Body:
This seems like an embarrassingly easy concept but I can't understand why this for loop is working the way it is. The question is simply asking "Given a binary array, find the maximum number of consecutive 1s in this array."

def main(nums):
 count = 0
 for num in nums:
   if num == 1:
    count+=1
   else:
    count = 0
main([1,1,0,1,1,1,0,0,1,1,1,1,1])

My question is, why does this for loop work? I expected the loop to print out the total count of 1's.


问:
Prove whether this language is decidable and recognizable
If L1 and L2 are languages we have a new language

```<code>INTERLACE(L1, L2) = {w1v1w2v2 . . . wnvn | w1w2 . . . wn ∈ L1, v1v2 . . . vn ∈ L2}.
</code>```

For example, if abc ∈ L1 and 123 ∈ L2, then a1b2c3 ∈ INTERLACE(L1, L2)

How can I prove that the INTERLACE is:

decidable ?

recognizable ?

I know how to show this language is regular.
For decidable I am not so sure..

Here's what I think:

To show that the class of decidable languages is closed under operation INTERLACE need to show that if A and B are two decidable languages, then there is method to find if INTERLACE language is decidable. Suppose A, B decidable languages and M1, M2 two TM who decide, respectively.

After I think I have to say how to construct the DFA that recognize the language?

答:
L1 and L2 decidable ==> INTERLACE(L1, L2) decidable

Citation from Wikipedia:

There are two equivalent major definitions for the concept of a recursive (also decidable) language:

     ...

     2. A recursive language is a formal language for which there exists a Turing machine that, when presented with any finite input string, halts and accepts if the string is in the language, and halts and rejects otherwise.

Using this definition:

If L1 and L2 are decidable, then algorithms (or Turing machines) M1 and M2 exist, so that:

M1 accepts all inputs w ∈ L1 and rejects all inputs w ∉ L1.

M2 accepts all inputs v ∈ L2 and rejects all inputs v ∉ L2.

Now let's construct algorithm M which accepts all inputs x ∈ INTERLACE(L1, L2) and rejects all inputs x ∉ INTERLACE(L1, L2), as follows:

Given an input x1 x2 .. xn.

If n is odd, reject the input, otherwise (n is even):

Run M1 for the input x1 x3 x5 .. xn-1. If M1 rejects this input, then M rejects its input and finishes, otherwise (M1 accepted its input):

Run M2 for the input x2 x4 x6 .. xn. If M2 rejects this input, then M rejects its input, otherwise M accepts its input.

One can easily prove that M is the decision algorithm for INTERLACE(L1, L2), thus, the language is decidable.

L1 and L2 recognizable ==> INTERLACE(L1, L2) recognizable

Citation from Wikipedia:

There are three equivalent definitions of a recursively enumerable (also recognizable) language:

     ...

     3. A recursively enumerable language is a formal language for which there exists a Turing machine (or other computable function) that will halt and accept when presented with any string in the language as input but may either halt and reject or loop forever when presented with a string not in the language. Contrast this to recursive languages, which require that the Turing machine halts in all cases.

The proof is very similar to the proof of the 'decidable' property.

If L1 and L2 are recognizable, then algorithms R1 and R2 exist, so that:

R1 accepts all inputs w ∈ L1 and rejects or loops forever for all inputs w ∉ L1.

R2 accepts all inputs v ∈ L2 and rejects or loops forever for all inputs v ∉ L2.

Let's construct algorithm R which accepts all inputs x ∈ INTERLACE(L1, L2) and rejects or loops forever for all inputs x ∉ INTERLACE(L1, L2):

Given an input x1 x2 .. xn.

If n is odd, reject the input, otherwise (n is even):

Run R1 for the input x1 x3 x5 .. xn-1. If R1 loops forever, then R loops forever as well ("automatically"). If R1 rejects this input, then R rejects its input and finishes, otherwise (if R1 accepts its input):

Run R2 for the input x2 x4 x6 .. xn. If R2 loops forever, then R loops forever as well. If R2 rejects this input, then R rejects its input, otherwise R accepts its input.

P.S. you were almost there, actually ;)

Body:
If L1 and L2 are languages we have a new language

INTERLACE(L1, L2) = {w1v1w2v2 . . . wnvn | w1w2 . . . wn ∈ L1, v1v2 . . . vn ∈ L2}.

For example, if abc ∈ L1 and 123 ∈ L2, then a1b2c3 ∈ INTERLACE(L1, L2)

How can I prove that the INTERLACE is:

decidable ?

recognizable ?

I know how to show this language is regular.
For decidable I am not so sure..

Here's what I think:

To show that the class of decidable languages is closed under operation INTERLACE need to show that if A and B are two decidable languages, then there is method to find if INTERLACE language is decidable. Suppose A, B decidable languages and M1, M2 two TM who decide, respectively.

After I think I have to say how to construct the DFA that recognize the language?


问:
How to use awk to search for min and max values of column in certain files
I know that awk is helpful in trying to find certain things in columns in files, but I'm not sure how to use it to find the min and max values of a column in a group of files. Any advice? To be specific I have four files in a directory that I want to go through awk with.</p>

答:
Try this: it will give min and max in file with comma seperated.

simple:

```<code>awk 'BEGIN {max = 0} {if ($6>max) max=$6} END {print max}' yourfile.txt
</code>```

or

```<code>awk 'BEGIN {min=1000000; max=0;}; { if($2<min && $2 != "") min = $2; if($2>max && $2 != "") max = $2; } END {print min, max}' file
</code>```

or more awkish way:

```<code>awk 'NR==1 { max=$1 ; min=$1 }
     FNR==NR { if ($1>=max) max=$1 ; $1<=min?min=$1:0 ; next}
     { $2=($1-min)/(max-min) ; print }' file file
</code>```

Body:
Try this: it will give min and max in file with comma seperated.

simple:

awk 'BEGIN {max = 0} {if ($6>max) max=$6} END {print max}' yourfile.txt

or

awk 'BEGIN {min=1000000; max=0;}; { if($2<min && $2 != "") min = $2; if($2>max && $2 != "") max = $2; } END {print min, max}' file

or more awkish way:

awk 'NR==1 { max=$1 ; min=$1 }
     FNR==NR { if ($1>=max) max=$1 ; $1<=min?min=$1:0 ; next}
     { $2=($1-min)/(max-min) ; print }' file file


问:
How do I connect to Gmail's IMAP server using oauth in Rails3?
I found the gmail_xoauth gem, which does most of what I need, but I also need to generate the oauth tokens (consumer_key and consumer_secret) from inside Rails3.

I am trying to integrate Gmail's oauth integration into my site and hence cannot use the python script that the above gem refers to. I would like my site to take the user to the authentication page and extract the consumer_key/secret tokens.

I am new to OAuth, so maybe there's something obvious that I am missing.

UPDATE: I solved the above, and have written a blog post with the details (since its too big to fit here).
http://blog.asif.in/blog/2012/03/03/google-oauth-and-rails/

答:
I'm not going to write the full code for you, but do you know PHP? You could have a look at the way this example works:

http://googlecodesamples.com/docs/php/Docs.php

...then make something similar in Ruby.

This is a Google Code Sample from the following site:

http://googlecodesamples.com/

ContentLicense: CC BY-SA 2.5


问:
SQL Syntax error near ' 'x')' at line 1 (Insert statement)
I'm getting problems trying to run this simple sql statement.

```<code>try{
                            stm.executeUpdate("INSERT INTO exam_somatique_6_12(id_p, id_m, id_u, Date, age, poids, taille, TA, exam_clinique, acuite_visuelle, acuite_auditive, age_puberte, conclusion) VALUES ("+idpat+","+idmed+","+idum+",'"+currentdate+"',"+txtage.getText()+","+txtpoids.getText()+","+txttaille.getText()+","+txtta.getText()+",'"+Clinique+"','"+Visuelle+"', '"+Auditive+"', "+Signe+", '"+txtobservation.getText()+"')");
                                    }

                                catch(SQLException e1)
                                {
                                    System.err.println(e1.getMessage());
                                }

                            dispose();
</code>```

I have no problem when executing it on mysql, but as soon as I try to do it in Java, I get this message error :

syntax error near ' 'x')' at line 1

And x is the result of the txtobservation.getText().

Also, I'm pretty sure it's not a quote problem, I'm using ' ' when it's a text, and not doing it when it's an integer.

Thanks for your help.

答:
You have to use PreparedStatement instead it is more secure and more helpful

```<code>String query = "INSERT INTO table(id_p, id_m, id_u, Date, age, poids, taille,
               TA, clinique, visuelle, auditive, puberte, observation)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

try (PreparedStatement ps = connection.prepareStatement(query) {

    ps.setInt(1, idpat);//set values to your query
    ps.setInt(2, idmed);
    ....
    ps.executeUpdate();//execute your query
}
</code>```

Note

getText it return String and not int and not float if txtage.getText() is int you have to convert it to int you can use :

```<code>Integer.parseInt(txtage.getText());//get int value form a String
Float.parseFloat(txtpoids.getText());//get float value from a String
</code>```

and so on

Body:
I'm getting problems trying to run this simple sql statement.

try{
                            stm.executeUpdate("INSERT INTO exam_somatique_6_12(id_p, id_m, id_u, Date, age, poids, taille, TA, exam_clinique, acuite_visuelle, acuite_auditive, age_puberte, conclusion) VALUES ("+idpat+","+idmed+","+idum+",'"+currentdate+"',"+txtage.getText()+","+txtpoids.getText()+","+txttaille.getText()+","+txtta.getText()+",'"+Clinique+"','"+Visuelle+"', '"+Auditive+"', "+Signe+", '"+txtobservation.getText()+"')");
                                    }

                                catch(SQLException e1)
                                {
                                    System.err.println(e1.getMessage());
                                }

                            dispose();

I have no problem when executing it on mysql, but as soon as I try to do it in Java, I get this message error :

syntax error near ' 'x')' at line 1

And x is the result of the txtobservation.getText().

Also, I'm pretty sure it's not a quote problem, I'm using ' ' when it's a text, and not doing it when it's an integer.

Thanks for your help.

Body:
You have to use PreparedStatement instead it is more secure and more helpful

String query = "INSERT INTO table(id_p, id_m, id_u, Date, age, poids, taille,
               TA, clinique, visuelle, auditive, puberte, observation)
               VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

try (PreparedStatement ps = connection.prepareStatement(query) {

    ps.setInt(1, idpat);//set values to your query
    ps.setInt(2, idmed);
    ....
    ps.executeUpdate();//execute your query
}

Note

getText it return String and not int and not float if txtage.getText() is int you have to convert it to int you can use :

Integer.parseInt(txtage.getText());//get int value form a String
Float.parseFloat(txtpoids.getText());//get float value from a String

and so on


问:
Rails routes url take out user_id
I currently have the standard

get 'profile/:id/view', to: 'profile#view', as: 'view'

which produces http://localhost:3000/profile/233/view

the controller is

```<code>def view
        @user = User.find(params[:id])
end
</code>```

How can I make a path that the url is http://localhost:3000/profile/view - leaving out the URL?

I was trying to do something like

```<code>def view(user_id)
        @user = User.find(user_id)
end
</code>```

But I'm not sure how to write that in the routes, or what the link_to path would look like for that?

I have been looking for a straight forward answer, but have not been able to find one.

Thanks in advance!

答:
You can change the route to

```<code>get 'profile/view', to: 'profile#view'
</code>```

And then in the controller, you can user current_user method which devise provides.

```<code>def view
  @user = current_user
end
</code>```

Title: Rails routes url take out user_id

Body:
I currently have the standard

get 'profile/:id/view', to: 'profile#view', as: 'view'

which produces http://localhost:3000/profile/233/view

the controller is

def view
        @user = User.find(params[:id])
end

How can I make a path that the url is http://localhost:3000/profile/view - leaving out the URL?

I was trying to do something like

def view(user_id)
        @user = User.find(user_id)
end

But I'm not sure how to write that in the routes, or what the link_to path would look like for that?

I have been looking for a straight forward answer, but have not been able to find one.

Thanks in advance!

Body:
You can change the route to

get 'profile/view', to: 'profile#view'

And then in the controller, you can user current_user method which devise provides.

def view
  @user = current_user
end


问:
Combining two bars into one sticky header where top bar changes height
I have two bars, a top bar and a breadcrumbs bar. The top bar is higher when the two bars are not combined. At some point, the bars combine into one sticky header. The following snippet shows this concept.

$(() => {
  const pivot = 500 - 145;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('after-pivot', scrollTop > pivot);
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.bar {
  width: 100%;
  display: block;
  -webkit-transition: all .25s ease;
  transition: all .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}</code>```

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.
```
</div>
</div>
</p>

<p>However, because the top bar is a different height when it is not combined with the bottom bar, the bottom bar "snaps" in place. If I would change the pivot point to where the bottom bar moves correctly, it will go over the top bar which looks even worse.</p>

<p><div class="snippet" data-lang="js" data-hide="true" data-console="false" data-babel="true">
<div class="snippet-code snippet-currently-hidden">
<pre class="snippet-code-js lang-js prettyprint-override"><code>$(() => {
  const pivot = 500 - 60;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('after-pivot', scrollTop > pivot);
  });
});</code>```

.bar {
  width: 100%;
  display: block;
  -webkit-transition: all .25s ease;
  transition: all .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top bar">
  I am a button
</div>
<div class="image">
</div>
<div class="breadcrumbs bar">
  <span>Home</span> - <span>My weird page</span>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.</p></code>```

What I want to accomplish is that when the bottom bar reaches the top bar, the margin-top on the top bar gradually reduces until both bars are at the very top.

I can accomplish this easily enough with javascript by defining two pivot points and calculating the margin-top based on this. This would become messy quickly when looking at the responsive site, because I need to move styling into the javascript.

function clamp(min, val, max) {
  return Math.max(min, Math.min(val, max));
}

$(() => {
  const pivotLower = 500 - 60;
  const pivotHigher = 500 - 145;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('.top.bar').css('margin-top', clamp(0, pivotLower - scrollTop, 85));
    $('body').toggleClass('after-pivot', scrollTop > pivotLower);
  });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.bar {
  width: 100%;
  display: block;
  -webkit-transition: background .25s ease;
  transition: background .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}</code>```

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.
```

Instead of margin-top I could use a real or pseudo-element with a height and alter it's height. We have min-height and max-height, meaning that if we are somehow able to force some element to be pushed down and thus increase the height of this element, we would be able to make this transition fluid. I am however not able to find any such interaction between a div that is position: fixed and an element in the normal flow.

Is it possible to use purely CSS and html structure, plus some javascript that sets one or two classes, to gradually change the margin between the top of the document and the top bar based on scroll height?

Codepen to mess with if you want.

答:
How about absolute positioning in the CSS, adding a .before-pivot class that makes it fixed via JS at ready as long as scrollTop < pivot? After this, during that short period, the .top.bar would have absolute positioning until it hits the top part at which point, an .after-pivot class would be added. Would still need a secondPivot point in order to work but in this case, there's no need for gradual margin decrease.

Basically, the classes of the .top.bar transitions from .before-pivot to nothing to .after-pivot.

$(() => {
  const pivot = 500 - 145;
  const secondPivot = 500 - 60;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('before-pivot', scrollTop < pivot);
    $('body').toggleClass('after-pivot', scrollTop > secondPivot);
  });
  $(window).scroll();
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.bar {
  width: 100%;
  display: block;
  -webkit-transition: background .25s ease;
  transition: background .25s ease;
}
.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}
.bar.top {
  height: 60px;
  position: absolute;
  top: 0;
  left: 0;
  margin-top: calc(440px);
  background: rgba(1, 1, 1, 0.1);
}
.before-pivot .bar.top {
  position: fixed;
  margin-top: 85px;
}
.after-pivot .bar.top {
  background: #000;
  position: fixed;
  margin-top: 0;
}
.bar.breadcrumbs {
  background: red;
  height: 40px;
}
.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}
.bar > * {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0; margin: 0;
}

p {
  margin: 5px 0;
}</code>```

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.

Aliquam vel tempor urna. Ut consectetur, augue non consectetur auctor, quam est blandit dui, quis accumsan sem tortor id nunc. Cras mollis posuere lacus, ultricies placerat metus. Phasellus convallis erat ac nulla semper sollicitudin. Vestibulum lacinia arcu ut efficitur iaculis. Duis in erat vitae mi maximus hendrerit. Mauris ut felis id est pretium porta sit amet eget nunc. Proin posuere fringilla suscipit. Proin eu porttitor magna. Duis convallis rhoncus nisi, sit amet tincidunt turpis fermentum sit amet. Integer sit amet bibendum ligula. Vestibulum nunc felis, facilisis mollis ultrices sed, auctor ut nibh. Nullam suscipit nibh sed tellus commodo, in laoreet dui posuere. Aliquam pulvinar arcu sem, in bibendum augue dapibus at. Quisque mattis, lectus ut ornare dictum, odio urna pretium nibh, at consectetur ipsum magna nec turpis. Cras vel risus eros.

Nunc ante mi, placerat id odio vel, tristique faucibus tortor. Morbi et neque ac velit tincidunt condimentum. Nunc id neque condimentum, pulvinar enim tincidunt, cursus turpis. Sed tempus a ligula accumsan lobortis. Donec consequat dui mauris, vitae hendrerit enim hendrerit sed. Quisque nisl lorem, varius in eros eget, ullamcorper rhoncus sem. Mauris euismod diam eu imperdiet interdum.

Aenean a diam vestibulum, eleifend erat ac, porta magna. In mattis lorem ac libero suscipit luctus a quis tortor. Curabitur quam urna, porta vel faucibus bibendum, efficitur molestie orci. Vivamus ultricies urna dui, ullamcorper aliquam dui semper maximus. Praesent posuere enim massa, eu scelerisque enim tincidunt at. Pellentesque vitae rutrum metus. Nam ac blandit lorem. Sed posuere ornare dui, non imperdiet urna posuere a. Nullam consectetur mi sit amet ornare pulvinar. Nunc laoreet blandit dolor, non elementum purus porta ac. Vestibulum quis auctor quam. Maecenas mi est, ultrices in elit sit amet, congue sodales nunc. Suspendisse eget tristique nulla. Vestibulum vulputate lacus eu nibh porta, ut condimentum diam tristique.

Suspendisse convallis sem dolor, vel congue urna molestie quis. Praesent eros felis, aliquet quis mattis vel, tincidunt vel purus. Pellentesque sollicitudin lorem eu sapien porttitor posuere eget a lacus. In sagittis tincidunt sodales. Cras iaculis velit id elit facilisis lobortis. Maecenas id aliquet elit. Aliquam pretium quam at urna tempus dictum. Cras ornare tellus dolor, ac finibus turpis consectetur ac. Curabitur eget vulputate urna, sed finibus nisi. Quisque molestie, tortor sed sagittis pharetra, dui est suscipit odio, vel venenatis quam sapien vel felis.
```

Body:
I have two bars, a top bar and a breadcrumbs bar. The top bar is higher when the two bars are not combined. At some point, the bars combine into one sticky header. The following snippet shows this concept.

$(() => {
  const pivot = 500 - 145;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('after-pivot', scrollTop > pivot);
  });
});

.bar {
  width: 100%;
  display: block;
  -webkit-transition: all .25s ease;
  transition: all .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.

However, because the top bar is a different height when it is not combined with the bottom bar, the bottom bar "snaps" in place. If I would change the pivot point to where the bottom bar moves correctly, it will go over the top bar which looks even worse.

$(() => {
  const pivot = 500 - 60;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('after-pivot', scrollTop > pivot);
  });
});

.bar {
  width: 100%;
  display: block;
  -webkit-transition: all .25s ease;
  transition: all .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.

What I want to accomplish is that when the bottom bar reaches the top bar, the margin-top on the top bar gradually reduces until both bars are at the very top.

I can accomplish this easily enough with javascript by defining two pivot points and calculating the margin-top based on this. This would become messy quickly when looking at the responsive site, because I need to move styling into the javascript.

function clamp(min, val, max) {
  return Math.max(min, Math.min(val, max));
}

$(() => {
  const pivotLower = 500 - 60;
  const pivotHigher = 500 - 145;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('.top.bar').css('margin-top', clamp(0, pivotLower - scrollTop, 85));
    $('body').toggleClass('after-pivot', scrollTop > pivotLower);
  });
});

.bar {
  width: 100%;
  display: block;
  -webkit-transition: background .25s ease;
  transition: background .25s ease;
}

.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}

.bar.top {
  height: 60px;
  position: fixed;
  top: 0;
  left: 0;
  margin-top: 85px;
  background: rgba(1, 1, 1, 0.1);
}

.after-pivot .bar.top {
  background: black;
  margin-top: 0;
}

.bar.breadcrumbs {
  background: red;
  height: 40px;
}

.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}

.bar>* {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0;
  margin: 0;
}

p {
  margin: 5px 0;
}

  I am a button

  Home - My weird page

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia
  ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.

Instead of margin-top I could use a real or pseudo-element with a height and alter it's height. We have min-height and max-height, meaning that if we are somehow able to force some element to be pushed down and thus increase the height of this element, we would be able to make this transition fluid. I am however not able to find any such interaction between a div that is position: fixed and an element in the normal flow.

Is it possible to use purely CSS and html structure, plus some javascript that sets one or two classes, to gradually change the margin between the top of the document and the top bar based on scroll height?

Codepen to mess with if you want.

Body:
How about absolute positioning in the CSS, adding a .before-pivot class that makes it fixed via JS at ready as long as scrollTop < pivot? After this, during that short period, the .top.bar would have absolute positioning until it hits the top part at which point, an .after-pivot class would be added. Would still need a secondPivot point in order to work but in this case, there's no need for gradual margin decrease.

Basically, the classes of the .top.bar transitions from .before-pivot to nothing to .after-pivot.

$(() => {
  const pivot = 500 - 145;
  const secondPivot = 500 - 60;
  $(window).on('scroll', () => {
    const scrollTop = $(window).scrollTop();
    $('body').toggleClass('before-pivot', scrollTop < pivot);
    $('body').toggleClass('after-pivot', scrollTop > secondPivot);
  });
  $(window).scroll();
});

.bar {
  width: 100%;
  display: block;
  -webkit-transition: background .25s ease;
  transition: background .25s ease;
}
.bar:before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  height: 100%;
}
.bar.top {
  height: 60px;
  position: absolute;
  top: 0;
  left: 0;
  margin-top: calc(440px);
  background: rgba(1, 1, 1, 0.1);
}
.before-pivot .bar.top {
  position: fixed;
  margin-top: 85px;
}
.after-pivot .bar.top {
  background: #000;
  position: fixed;
  margin-top: 0;
}
.bar.breadcrumbs {
  background: red;
  height: 40px;
}
.after-pivot .bar.breadcrumbs {
  position: fixed;
  top: 60px;
}
.bar > * {
  vertical-align: middle;
}

.button {
  height: 20px;
  text-decoration: none;
  color: white;
  background: grey;
  padding: 4px 10px;
}

.image {
  height: 500px;
  background: url("http://placehold.it/2000x500");
  background-position: center center;
  background-repeat: no-repeat;
  background-size: cover;
}

body {
  height: 500vh;
  padding: 0; margin: 0;
}

p {
  margin: 5px 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="top bar">
  <a href="#" class="button">I am a button</a>
</div>
<div class="image">
</div>
<div class="breadcrumbs bar">
  <span>Home</span> - <span>My weird page</span>
</div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque lacus augue, fermentum sed dui vel, imperdiet pretium risus. Nam quis diam eu tortor efficitur molestie. Nulla non nibh felis. Proin eget malesuada urna, sed bibendum ex. Mauris lacinia ligula in ipsum ornare pulvinar. Pellentesque vitae volutpat nibh, in convallis velit. Aenean sed ex massa. Vestibulum ullamcorper purus et erat dignissim tristique. Pellentesque et viverra nisi.</p>

<p>Aliquam vel tempor urna. Ut consectetur, augue non consectetur auctor, quam est blandit dui, quis accumsan sem tortor id nunc. Cras mollis posuere lacus, ultricies placerat metus. Phasellus convallis erat ac nulla semper sollicitudin. Vestibulum lacinia arcu ut efficitur iaculis. Duis in erat vitae mi maximus hendrerit. Mauris ut felis id est pretium porta sit amet eget nunc. Proin posuere fringilla suscipit. Proin eu porttitor magna. Duis convallis rhoncus nisi, sit amet tincidunt turpis fermentum sit amet. Integer sit amet bibendum ligula. Vestibulum nunc felis, facilisis mollis ultrices sed, auctor ut nibh. Nullam suscipit nibh sed tellus commodo, in laoreet dui posuere. Aliquam pulvinar arcu sem, in bibendum augue dapibus at. Quisque mattis, lectus ut ornare dictum, odio urna pretium nibh, at consectetur ipsum magna nec turpis. Cras vel risus eros.</p>

<p>Nunc ante mi, placerat id odio vel, tristique faucibus tortor. Morbi et neque ac velit tincidunt condimentum. Nunc id neque condimentum, pulvinar enim tincidunt, cursus turpis. Sed tempus a ligula accumsan lobortis. Donec consequat dui mauris, vitae hendrerit enim hendrerit sed. Quisque nisl lorem, varius in eros eget, ullamcorper rhoncus sem. Mauris euismod diam eu imperdiet interdum.</p>

<p>Aenean a diam vestibulum, eleifend erat ac, porta magna. In mattis lorem ac libero suscipit luctus a quis tortor. Curabitur quam urna, porta vel faucibus bibendum, efficitur molestie orci. Vivamus ultricies urna dui, ullamcorper aliquam dui semper maximus. Praesent posuere enim massa, eu scelerisque enim tincidunt at. Pellentesque vitae rutrum metus. Nam ac blandit lorem. Sed posuere ornare dui, non imperdiet urna posuere a. Nullam consectetur mi sit amet ornare pulvinar. Nunc laoreet blandit dolor, non elementum purus porta ac. Vestibulum quis auctor quam. Maecenas mi est, ultrices in elit sit amet, congue sodales nunc. Suspendisse eget tristique nulla. Vestibulum vulputate lacus eu nibh porta, ut condimentum diam tristique.</p>

<p>Suspendisse convallis sem dolor, vel congue urna molestie quis. Praesent eros felis, aliquet quis mattis vel, tincidunt vel purus. Pellentesque sollicitudin lorem eu sapien porttitor posuere eget a lacus. In sagittis tincidunt sodales. Cras iaculis velit id elit facilisis lobortis. Maecenas id aliquet elit. Aliquam pretium quam at urna tempus dictum. Cras ornare tellus dolor, ac finibus turpis consectetur ac. Curabitur eget vulputate urna, sed finibus nisi. Quisque molestie, tortor sed sagittis pharetra, dui est suscipit odio, vel venenatis quam sapien vel felis.</p>


问:
Download file using token based API
I'm creating a web application with Vue.js(front end) + Laravel(back end) and I structured the whole app to communicate with the back end through api routes. The requests pass through a middleware for authentication using a token (passport in Laravel). At some point I need to download some files, but I wouldn't know how to make it happend because I have no way to identificate or authenticate the user though web routes. I could send byte data from the API through an ajax request but then it would be difficult to make the user download the file from the javascript (at least it would be hard to make things work on every browser).

So what's the best approach to this problem?

答:
We recently had to solve this problem.

First we sent the file stream via ajax request and then download the file via HTML5 file API, but it caused a lot of problems for files > 5MB.

The solution that we implemented at the end, and sounds best is to create a temporary file URL with some temporary token, for that file to be downloaded. With an expiration like 5 minutes or whatever suits your need. On your API call send that new URL and open in new tab or download or any other thing you want to do.

EDIT:
We were using Amazon s3 for storage so the authentication was not a problem, but you will need to make changes to authentication layer to allow temp URL access without token to reach your temp file handling controller.

Title: Download file using token based API


问:
Does the use of es6 named imports reduce the bundle size when using webpack
I need to understand when I use a named import like this

```<code>import { render } from 'react-dom'
</code>```

does webpack include in the bundle only the render method or the whole module especially when using tree shaking by setting module to false in babel configuration and let webpack take care about them?

Also in the case of importing react

```<code>import React from 'react'
</code>```

&&

```<code>import React, { Component, PropTypes } from 'react'
</code>```

what's the right way?

答:
Tree-Shaking is applicable for modules which can be statically analysed (to get the entire dependency tree without running the code) -
and it is ONLY for ES2015 Modules and NOT CommonJS(node) modules.

react, react-dom, as of this writing (react@15.4.x), are NOT published as ES2015 modules. So either of these -

```<code>import { render } from "react-dom";
</code>```

or

```<code>import ReactDOM from "react-dom";
</code>```

will result in the entire react-dom being included in your bundle. The same applies for react and other libraries which are published as CommonJS modules or UMD.

Body:
I need to understand when I use a named import like this

import { render } from 'react-dom'

does webpack include in the bundle only the render method or the whole module especially when using tree shaking by setting module to false in babel configuration and let webpack take care about them?

Also in the case of importing react

import React from 'react'

&&

import React, { Component, PropTypes } from 'react'

what's the right way?

Body:
Tree-Shaking is applicable for modules which can be statically analysed (to get the entire dependency tree without running the code) -
and it is ONLY for ES2015 Modules and NOT CommonJS(node) modules.

react, react-dom, as of this writing (react@15.4.x), are NOT published as ES2015 modules. So either of these -

import { render } from "react-dom";

or

import ReactDOM from "react-dom";

will result in the entire react-dom being included in your bundle. The same applies for react and other libraries which are published as CommonJS modules or UMD.


问:
float object not callable error while calculating sum of list in Python
When i try to add up list elements it produces below error

```<code>print weights
print sum(weights)
</code>```

I get the following error

```<code>[0.2, 0.2, 0.2, 0.2, 0.2]
  TypeError Traceback (most recent call last)
<ipython-input-77-f2d5440b3427> in <module>()
      1 print weights
----> 2 print sum(weights)
      3

 TypeError: 'float' object is not callable
</code>```

答: Somewhere in the unseen code above, you're assigning a value to sum.

Body:
When i try to add up list elements it produces below error

print weights
print sum(weights)

I get the following error

[0.2, 0.2, 0.2, 0.2, 0.2]
  TypeError Traceback (most recent call last)
<ipython-input-77-f2d5440b3427> in <module>()
      1 print weights
----> 2 print sum(weights)
      3

 TypeError: 'float' object is not callable


问:
Firebase createUserWithEmailAndPassword does not work
I am following the basic tutorial in order to create an e-mail / password authentication using Firebase.

```<code>  mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());

                    if (!task.isSuccessful()) {
                        Toast.makeText(MainActivity.this, R.string.auth_failed,
                                Toast.LENGTH_SHORT).show();
                    }

                    hideProgressDialog();
                }
 });
</code>```

But whenever I try to create an account (with a valid e-mail address and a diversity of passwords, with caps, numbers, high length) it displays my failure Toast.

What could I be doing wrong?

答: Go to Firebase console -> Authentication -> SIGN-IN METHOD -> enable Email/Password

Body:
I am following the basic tutorial in order to create an e-mail / password authentication using Firebase.

  mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    Log.d(TAG, "createUserWithEmail:onComplete:" + task.isSuccessful());

                    if (!task.isSuccessful()) {
                        Toast.makeText(MainActivity.this, R.string.auth_failed,
                                Toast.LENGTH_SHORT).show();
                    }

                    hideProgressDialog();
                }
 });

But whenever I try to create an account (with a valid e-mail address and a diversity of passwords, with caps, numbers, high length) it displays my failure Toast.

What could I be doing wrong?


问:
Recommendation for Messaging Server for Chat Room
Need some recommendation for a Instant Messenger/Chatroom Application for web/mobile.

MQTT seems to fit the bill in terms of reliability. However Chat room principles involve the following challenges.

User is subscribed to ONE room/topic at the time.

User in a chatroom can block one or more participants in the room preventing them for reading any messages that the User types.

Administrator can KICK a User out of the chatroom or throw him to another room (Lobby for example).

Messages have to be intercepted for spam checks/content modified to render smileys and other codes based on what messaging pack the User might have purchased. Complete control over the message content.

With these in mind is writing a NodeJS socket server an ideal solution or MQTT with plugin code is a way to go?

Is MQTT even a right fit for the requirement? Need some inputs.

答:
This strikes me as a primarily opinion based question, but I'll take a crack at it.

Certainly you can do this... if you look on Github there are several projects (For example: https://github.com/happiestcoder/mqtt-chat) that achieve something similar. MQTT is lightweight and I find it a joy to work with--and understand--in comparison to other protocols so if you want to, go for it! I'm all for more people using MQTT!

But it does seem like the consensus is that MQTT is more useful for low-bandwidth M2M than instant messaging / chatting. A better alternative is XMPP. (Which is mentioned in your title, so maybe there is confusion here?) XMPP offers quite a few features--most notably better identity tracking--and extensions that seem well suited to your use.

Here is a nice, simple discussion of the difference between the two protocols which i think will help you: https://servicelab.org/2015/05/08/xmpp-versus-mqtt-comparing-apples-with-pears/ . In summary, MQTT is simpler and far more efficient, but XMPP offers a more robust feature set at the cost of processor power and bandwidth. From my perspective XMPP is the clear winner for a chat room whereas MQTT is far superior for high-volume metric communication.


问:
Laravel 5.4 migrate key is too long error
when I run migrate command with laravel 5.4 I get an error "specific key was too long", I searched and found many people also face this error. The common is add Schema::defaultStringLength(191); in AppServiceProvider.php. But the doc https://laravel-news.com/laravel-5-4-key-too-long-error says it is for those mysql version older than 5.7.7. But my version is 5.7.14(mysql  Ver 14.14 Distrib 5.7.14, for Win64 (x86_64)), and I already set mysql default charset to utf8mb4(show variables like "%char%"):

So I think I do not need to change anything but I still get the problem. It makes me confused. Who can help me? Thanks.

答:
Set innodb_file_format=Barracuda

Set innodb_large_prefix=1

Set innodb_default_row_format=dynamic

Step 1 (innodb_file_format) and 2 (innodb_large_prefix) works on older Mysql versions, including MariaDB. I do not know the lower version bounds for these. Mysql 5.7.7 changed the defaults for these settings, but they existed earlier.

Step 3 (innodb_default_row_format) requires Mysql 5.7.9 or newer.

For the sake of documentation; a workaround if you're missing the innodb_default_row_format setting is to use the engine innodb row_format=dynamic. This abuses the fact that Laravel appends this to the CREATE TABLE statement without any escaping, resulting in ... ENGINE=innodb row_format=dynamic.

Laravel 5.2.14 introduced the ability to specify the engine in config/database.php. If you're on an older version you have to specify this in every migration that creates a table. $table->engine = 'innodb row_format=dynamic';


问:
Redirecting stdout from multiple processes to python Logging module
I have a python script that launches a number of user processes using subprocess.Popen. Each process stdout is redirected to a unique file. For example the I launch each process as follows

```<code>proc = my_proc
for p in range(1, max_p, 1):
    log_file = proc + "_" + str(p) + ".log"
    log = open(log_file, "w+")
    subprocess.Popen([my_proc, p], shell = False, stdout = log)
</code>```

I would like to rotate these files when they become too big. What would the best way of doing this? I would like to use the logging module but I dont think this is its intended use

Thanks

答:
Not a pythonic solution; but on linux systems I prefer using logrotate to automatically rotate my logs.  Check to see if its installed on your system (On ubuntu say there is a directory called /etc/logrotate.d/ with files automatically run via cron).  This may or may not be preferred to having log rotation run from within the application.

It's very configurable, e.g., allows compression of older files keeps N files via rotate N command, rotates when the cron over "size 100k", and looking at man logrotate, its very straightforward to setup.

From the man page here's a sample file

```<code>   # sample logrotate configuration file
   compress

   /var/log/messages {
       rotate 5
       weekly
       postrotate
           /usr/bin/killall -HUP syslogd
       endscript
   }

   "/var/log/httpd/access.log" /var/log/httpd/error.log {
       rotate 5
       mail www@my.org
       size 100k
       sharedscripts
       postrotate
           /usr/bin/killall -HUP httpd
       endscript
   }
</code>```

Body:
I have a python script that launches a number of user processes using subprocess.Popen. Each process stdout is redirected to a unique file. For example the I launch each process as follows

proc = my_proc
for p in range(1, max_p, 1):
    log_file = proc + "_" + str(p) + ".log"
    log = open(log_file, "w+")
    subprocess.Popen([my_proc, p], shell = False, stdout = log)

I would like to rotate these files when they become too big. What would the best way of doing this? I would like to use the logging module but I dont think this is its intended use

Thanks

Body:
Not a pythonic solution; but on linux systems I prefer using logrotate to automatically rotate my logs.  Check to see if its installed on your system (On ubuntu say there is a directory called /etc/logrotate.d/ with files automatically run via cron).  This may or may not be preferred to having log rotation run from within the application.

It's very configurable, e.g., allows compression of older files keeps N files via rotate N command, rotates when the cron over "size 100k", and looking at man logrotate, its very straightforward to setup.

From the man page here's a sample file

   # sample logrotate configuration file
   compress

   /var/log/messages {
       rotate 5
       weekly
       postrotate
           /usr/bin/killall -HUP syslogd
       endscript
   }

   "/var/log/httpd/access.log" /var/log/httpd/error.log {
       rotate 5
       mail www@my.org
       size 100k
       sharedscripts
       postrotate
           /usr/bin/killall -HUP httpd
       endscript
   }


问:
React-Native can't run Android - react-native-maps:compileReleaseJavaWithJavac
I have a react-native project and everything works great on ios but when I try to run it on android I get this error ':react-native-maps:compileReleaseJavaWithJavac' > Could not find tools.jar. I'm not sure what it means and I have done some research and found this Stackoverflow Question However, it doesn't seem to be my case.

Does anyone know what this error means?

build.gradle

```<code>dependencies {
    compile project(':react-native-push-notification')
    compile project(':react-native-prompt-android')
    compile project(':react-native-maps')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile(project(':react-native-maps')){
        exclude group: 'com.google.android.gms', module: 'play-services-base'
        exclude group: 'com.google.android.gms', module: 'play-services-maps'
    }
    compile 'com.google.android.gms:play-services-base:10.0.1'
    compile 'com.google.android.gms:play-services-maps:10.0.1'
    compile "com.facebook.react:react-native:+"  // From node_modules
}
</code>```

答: Android development requires to have the JDK installed on your computer. You have to set the environment variable JAVA_HOME to a valid JDK. The error could be because you don't have a JDK on your computer. Try to Launch Android Studio and check that the JDK is here by creating an empty project, go to File-> Project Structure and look at the JDK location.

Body:
I have a react-native project and everything works great on ios but when I try to run it on android I get this error ':react-native-maps:compileReleaseJavaWithJavac' > Could not find tools.jar. I'm not sure what it means and I have done some research and found this Stackoverflow Question However, it doesn't seem to be my case.

Does anyone know what this error means?

build.gradle

dependencies {
    compile project(':react-native-push-notification')
    compile project(':react-native-prompt-android')
    compile project(':react-native-maps')
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile(project(':react-native-maps')){
        exclude group: 'com.google.android.gms', module: 'play-services-base'
        exclude group: 'com.google.android.gms', module: 'play-services-maps'
    }
    compile 'com.google.android.gms:play-services-base:10.0.1'
    compile 'com.google.android.gms:play-services-maps:10.0.1'
    compile "com.facebook.react:react-native:+"  // From node_modules
}


问:
In Ruby FFI when I return a dynamically allocated string should I free it?
I have the following function in C

```<code>char* strfunc()
{
   char* ch=calloc(100,1);
   strcpy(ch,"hello");
   return ch;
}
</code>```

Then in ruby I have

```<code>module XYZ
   extend FFI::Library
   ffi_lib "mylib.so"
   attach_function :strfunc, [] , :string
end
</code>```

Should I import free to free memory allocated to the string returned or will Ruby GC do that for me?

答:
Nor FFI, nor ruby GC will free it automatically, because, they does not know it's malloc'd and not just some static memory.

You should free it manually with libc's free() call. Please, reference to this ticket https://github.com/ffi/ffi/issues/467 for examples.

Body:
I have the following function in C

char* strfunc()
{
   char* ch=calloc(100,1);
   strcpy(ch,"hello");
   return ch;
}

Then in ruby I have

module XYZ
   extend FFI::Library
   ffi_lib "mylib.so"
   attach_function :strfunc, [] , :string
end

Should I import free to free memory allocated to the string returned or will Ruby GC do that for me?


问:
SplashScreen in react native
I need to make an image as a background for the whole first screen as a SplashScreen and after some fixed time it shows the other component.
I created two components Home and SplashScreen and here is the code i'm using: </p>

```<code>componentDidMount() {
    SplashScreen.hide();
}
    render() {

return(

    <View>
        <SplashScreen/>
        <Home/>
    </View>

)
    }
</code>```

<p>Please any help or idea </p>

答:
You need to implement this in Javascript land.

Top most component would hold a flag indicating to render splash screen.
Update this flag after specified amount of time and render desired content.

Dummy implementation may look like this...

```<code>class App extends Component {
  state = {
    ready: false,
  }

  componentDidMount () {
    setTimeout(() => {
      this.setState({ ready: true })
    }, 5000)
  }

  render() {
    if (this.state.ready === false) {
      return <Splash />
    }

    return this.props.children;
  }
}

// Usage example:
<App>
  <RouterOrSomething />
</App>
</code>```

Title: SplashScreen in react native

Body:
I need to make an image as a background for the whole first screen as a SplashScreen and after some fixed time it shows the other component.
I created two components Home and SplashScreen and here is the code i'm using:

componentDidMount() {
    SplashScreen.hide();
}
    render() {

return(

    <View>
        <SplashScreen/>
        <Home/>
    </View>

)
    }

Please any help or idea

Body:
You need to implement this in Javascript land.

Top most component would hold a flag indicating to render splash screen.
Update this flag after specified amount of time and render desired content.

Dummy implementation may look like this...

class App extends Component {
  state = {
    ready: false,
  }

  componentDidMount () {
    setTimeout(() => {
      this.setState({ ready: true })
    }, 5000)
  }

  render() {
    if (this.state.ready === false) {
      return <Splash />
    }

    return this.props.children;
  }
}

// Usage example:
<App>
  <RouterOrSomething />
</App>


问:
Back button on toolbar
I am working on a webview, and I noticed there is no Back or Next system button for the toolbar. I'm asking this because I see it for the nav bar, and in safari on an iPhone. So if someone could clear this up for me, that would be great!</p>

答:
first I suggest you to take a look at apple documentation here

As for the navigation buttons: create a toolbar or smth else depends on design, and add necessary buttons(back/forward etc) actions in your .swift file

```<code>@IBAction func goBack(sender: UIBarButtonItem-or-UIButton) {
    self.webView.goBack()
}

@IBAction func reload(sender: UIBarButtonItem-or-UIButton) {
    self.webView.reload()
}

@IBAction func forward(sender: UIBarButtonItem-or-UIButton) {
    self.webView.goForward()
}
</code>```

Title: Back button on toolbar

Body:
first I suggest you to take a look at apple documentation here

As for the navigation buttons: create a toolbar or smth else depends on design, and add necessary buttons(back/forward etc) actions in your .swift file

@IBAction func goBack(sender: UIBarButtonItem-or-UIButton) {
    self.webView.goBack()
}

@IBAction func reload(sender: UIBarButtonItem-or-UIButton) {
    self.webView.reload()
}

@IBAction func forward(sender: UIBarButtonItem-or-UIButton) {
    self.webView.goForward()
}


问:
LoadError in Devise (Cannot load bcrypt)
So I'm having issues with creating users with Devise.
It's an issue with "bcrypt".

Here is the error that's being generated

I looked at a few similar threads here and the solution was to install the bcrypt gem for Ruby.
And so I went to rubygems.org and added the line in gem file then ran bundle install.

However, after that I try to run the server but it fails for some reason. Server won't start. Here is the error I received in GitBash:

```<code>Zak@ZAKARIA ~/Desktop/Work/raddit (add_users)
$ rails s
c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/dependen
cies.rb:293:in `require': cannot load such file -- bcrypt_ext (LoadError)
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:293:in `block in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:259:in `load_dependency'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:293:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcry
pt.rb:16:in `rescue in <top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcry
pt.rb:12:in `<top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:91:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:91:in `block (2 levels) in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:86:in `each'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:86:in `block in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:75:in `each'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:75:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler.rb:106:
in `require'
        from c:/Users/Zak/Desktop/Work/raddit/config/application.rb:7:in `<top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:88:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:88:in `block in server'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:85:in `tap'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:85:in `server'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:49:in `run_command!'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands.
rb:18:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'
</code>```

NOTE: Before adding the gem, the server would run just fine.

Also here is my gem file

```<code>gem 'rails', '~> 5.0.2'
gem 'sqlite3'
gem 'puma', '~> 3.0'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'devise', '~> 4.2', '>= 4.2.1'
gem 'jquery-rails'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bcrypt', '~> 3.1', '>= 3.1.11'

group :development, :test do
   gem 'byebug', platform: :mri
end

group :development do
  gem 'web-console', '>= 3.3.0'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
</code>```

答:
Based on ajeferson's asnwer.

This thread has the solution: github.com/codahale/bcrypt-ruby/issues/142

Body:
So I'm having issues with creating users with Devise.
It's an issue with "bcrypt".

Here is the error that's being generated

I looked at a few similar threads here and the solution was to install the bcrypt gem for Ruby.
And so I went to rubygems.org and added the line in gem file then ran bundle install.

However, after that I try to run the server but it fails for some reason. Server won't start. Here is the error I received in GitBash:

Zak@ZAKARIA ~/Desktop/Work/raddit (add_users)
$ rails s
c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_support/dependen
cies.rb:293:in `require': cannot load such file -- bcrypt_ext (LoadError)
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:293:in `block in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:259:in `load_dependency'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-5.0.2/lib/active_sup
port/dependencies.rb:293:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcry
pt.rb:16:in `rescue in <top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bcrypt-3.1.11-x86-mingw32/lib/bcry
pt.rb:12:in `<top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:91:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:91:in `block (2 levels) in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:86:in `each'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:86:in `block in require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:75:in `each'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler/runtime
.rb:75:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.13.7/lib/bundler.rb:106:
in `require'
        from c:/Users/Zak/Desktop/Work/raddit/config/application.rb:7:in `<top (required)>'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:88:in `require'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:88:in `block in server'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:85:in `tap'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:85:in `server'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands/
commands_tasks.rb:49:in `run_command!'
        from c:/RailsInstaller/Ruby2.3.0/lib/ruby/gems/2.3.0/gems/railties-5.0.2/lib/rails/commands.
rb:18:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `'

NOTE: Before adding the gem, the server would run just fine.

Also here is my gem file

gem 'rails', '~> 5.0.2'
gem 'sqlite3'
gem 'puma', '~> 3.0'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'devise', '~> 4.2', '>= 4.2.1'
gem 'jquery-rails'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bcrypt', '~> 3.1', '>= 3.1.11'

group :development, :test do
   gem 'byebug', platform: :mri
end

group :development do
  gem 'web-console', '>= 3.3.0'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]