问:
Spring boot OneToOne relationship problem
I need get data from database without some fields, but I receive or ALL data (with relationship) or error.

```<code>import org.springframework.data.domain.Persistable
import org.springframework.data.util.ProxyUtils
import java.io.Serializable
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.MappedSuperclass
import javax.persistence.Transient

@MappedSuperclass
abstract class AbstractEntity<T : Serializable>() : Persistable<T> {

    companion object {
        private val serialVersionUID = -5554308939380869754L
    }

    @Id
    @GeneratedValue
    private var id: T? = null

    override fun getId(): T? {
        return id
    }

    fun setId(id:T){
        this.id = id
    }

    /**
     * Must be [Transient] in order to ensure that no JPA provider complains because of a missing setter.
     *
     * @see org.springframework.data.domain.Persistable.isNew
     */
    @Transient
    override fun isNew() = null == getId()

    override fun toString() = "Entity of type ${this.javaClass.name} with id: $id"

    override fun equals(other: Any?): Boolean {
        other ?: return false

        if (this === other) return true

        if (javaClass != ProxyUtils.getUserClass(other)) return false

        other as AbstractEntity<*>

        return if (null == this.getId()) false else this.getId() == other.getId()
    }

    override fun hashCode(): Int {
        return 31
    }
}
</code>```

ProductEntity:

```<code>@Entity
@Table(name = "product")
class ProductEntity : AbstractEntity<Long> {
    @Column(name = "product_name")
    var productName: String = ""
    @Column(name = "description", length = 65535, columnDefinition = "text")
    var description: String = ""
    @Column(name = "product_model")
    var productModel: String = ""
    @Column(name = "product_articul")
    var productArticul: String = ""
    @Column(name = "product_count")
    var productCount: Int = 0
    @Column(name = "is_available")
    var isAvailable: Boolean = false
    @Column(name = "product_price")
    var productPrice: Float = 0f
    @Column(name = "product_extra")
    var productExtra: Float = 0f
    @Column(name = "product_total_price")
    var productTotalPrice: Float = 0f
    @OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false, fetch = FetchType.LAZY)
    var productCategoryProperty: ProductCategoryPropertyEntity = ProductCategoryPropertyEntity()
    @OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], fetch = FetchType.LAZY)
    var category: CategoryEntity = CategoryEntity()
    @Column(name = "images")
    var images: Array<String?> = arrayOf()
    @Column(name = "keywords", length = 65535, columnDefinition = "text")
    var keywords: String? = ""

    constructor() : super() {
    }

    fun convertToDto(): ProductDto {
        return ProductDto(id, productName, description, productModel, productArticul,
                productCount, productPrice, productExtra, productTotalPrice, isAvailable,
                productCategoryProperty?.convertToDto(), category?.convertToDto(), images, keywords)
    }
}
</code>```

ProductCategoryPropertyEntity:

```<code>import ua.jdroidcoder.jdcshop.dto.ProductCategoryPropertyDto
import javax.persistence.*

@Entity
@Table(name = "product_category_property")
class ProductCategoryPropertyEntity : AbstractEntity<Long> {

    @OneToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false)
    var simpleProperties: MutableList<ProductPropertySimpleEntity> = ArrayList()

    @OneToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false)
    var advancedProperties: MutableList<ProductPropertySimpleEntity> = ArrayList()

    constructor() : super() {
    }

    fun convertToDto(): ProductCategoryPropertyDto {
        val simple = ProductCategoryPropertyDto()
        simple.id = id
        simpleProperties?.forEach {
            simple.simpleProperties.add(it.convertToDto())
        }
        advancedProperties?.forEach {
            simple.advancedProperties.add(it.convertToDto())
        }
        return simple
    }
}
</code>```

ProductPropertySimpleEntity:

```<code>import ua.jdroidcoder.jdcshop.dto.PropertySimpleDto
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table

@Entity
@Table(name = "product_property_simple")
class ProductPropertySimpleEntity : AbstractEntity<Long> {
    @Column(name = "property_name")
    var propertyName: String = ""

    @Column(name = "property_value")
    var propertyValue: String = ""

    @Column(name = "parent_id")
    var parentId: Long? = null

    @Column(name = "parent_id_in_category")
    var parentIdInCategory: Long? = null

    @Column(name = "id_in_category")
    var idInCategory: Long? = null

    constructor() : super() {
    }

    fun convertToDto(): PropertySimpleDto {
       return PropertySimpleDto(id!!,propertyName,parentId,propertyValue)
    }
}
</code>```

When I try make select, I see:

```<code>Hibernate: select productent0_.id as id1_3_, productent0_.category_id as categor13_3_, productent0_.description as descript2_3_, productent0_.images as images3_3_, productent0_.is_available as is_avail4_3_, productent0_.keywords as keywords5_3_, productent0_.product_articul as product_6_3_, productent0_.product_category_property_id as product14_3_, productent0_.product_count as product_7_3_, productent0_.product_extra as product_8_3_, productent0_.product_model as product_9_3_, productent0_.product_name as product10_3_, productent0_.product_price as product11_3_, productent0_.product_total_price as product12_3_ from product productent0_
Hibernate: select categoryen0_.id as id1_0_0_, categoryen0_.category_name as category2_0_0_, categoryen0_.prom_category_id as prom_cat3_0_0_ from category categoryen0_ where categoryen0_.id=?
Hibernate: select productcat0_.id as id1_4_0_ from product_category_property productcat0_ where productcat0_.id=?
Hibernate: select simpleprop0_.product_category_property_entity_id as product_1_6_0_, simpleprop0_.simple_properties_id as simple_p2_6_0_, productpro1_.id as id1_7_1_, productpro1_.id_in_category as id_in_ca2_7_1_, productpro1_.parent_id as parent_i3_7_1_, productpro1_.parent_id_in_category as parent_i4_7_1_, productpro1_.property_name as property5_7_1_, productpro1_.property_value as property6_7_1_ from product_category_property_simple_properties simpleprop0_ inner join product_property_simple productpro1_ on simpleprop0_.simple_properties_id=productpro1_.id where simpleprop0_.product_category_property_entity_id=?
Hibernate: select advancedpr0_.product_category_property_entity_id as product_1_5_0_, advancedpr0_.advanced_properties_id as advanced2_5_0_, productpro1_.id as id1_7_1_, productpro1_.id_in_category as id_in_ca2_7_1_, productpro1_.parent_id as parent_i3_7_1_, productpro1_.parent_id_in_category as parent_i4_7_1_, productpro1_.property_name as property5_7_1_, productpro1_.property_value as property6_7_1_ from product_category_property_advanced_properties advancedpr0_ inner join product_property_simple productpro1_ on advancedpr0_.advanced_properties_id=productpro1_.id where advancedpr0_.product_category_property_entity_id=?
</code>```

I know that it's happens via @OneToOne, but I can't seek solution ;(

I need receive only some fields like: productName, description, productModel, productArticul, productCount...

Thanks for help, guys!

答:
@OneToOne is tricky if you allow null value.

JPA must try to access the record form the other table even if the property is signed with lazy-initialization, because it has to decide whether to set the property to null or a proxy-object.

It cannot set it null automatically, because there can be an associated object.
It cannot create the proxy-object automatically either, because there is no designated column in the table for the id of that property (Because one-to-one relationship is mapped by shared PK by default).

So the only way to decide if the associated entity does exist is trying to load its id from it's own table. If this query returns null then no associated entity, otherwise the JPA can create a proxy object from this id.

If you really need to avoid this extra request then add a foreign key to product_category_property table into the product table.

```<code>@OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false, fetch = FetchType.LAZY)
@JoinColumn(name='product_category_property')
var productCategoryProperty: ProductCategoryPropertyEntity = ProductCategoryPropertyEntity()
</code>```

You can find further explanations in this topic.

Body:
I need get data from database without some fields, but I receive or ALL data (with relationship) or error.

import org.springframework.data.domain.Persistable
import org.springframework.data.util.ProxyUtils
import java.io.Serializable
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.MappedSuperclass
import javax.persistence.Transient

@MappedSuperclass
abstract class AbstractEntity<T : Serializable>() : Persistable<T> {

    companion object {
        private val serialVersionUID = -5554308939380869754L
    }

    @Id
    @GeneratedValue
    private var id: T? = null

    override fun getId(): T? {
        return id
    }

    fun setId(id:T){
        this.id = id
    }

    /**
     * Must be [Transient] in order to ensure that no JPA provider complains because of a missing setter.
     *
     * @see org.springframework.data.domain.Persistable.isNew
     */
    @Transient
    override fun isNew() = null == getId()

    override fun toString() = "Entity of type ${this.javaClass.name} with id: $id"

    override fun equals(other: Any?): Boolean {
        other ?: return false

        if (this === other) return true

        if (javaClass != ProxyUtils.getUserClass(other)) return false

        other as AbstractEntity<*>

        return if (null == this.getId()) false else this.getId() == other.getId()
    }

    override fun hashCode(): Int {
        return 31
    }
}

ProductEntity:

@Entity
@Table(name = "product")
class ProductEntity : AbstractEntity<Long> {
    @Column(name = "product_name")
    var productName: String = ""
    @Column(name = "description", length = 65535, columnDefinition = "text")
    var description: String = ""
    @Column(name = "product_model")
    var productModel: String = ""
    @Column(name = "product_articul")
    var productArticul: String = ""
    @Column(name = "product_count")
    var productCount: Int = 0
    @Column(name = "is_available")
    var isAvailable: Boolean = false
    @Column(name = "product_price")
    var productPrice: Float = 0f
    @Column(name = "product_extra")
    var productExtra: Float = 0f
    @Column(name = "product_total_price")
    var productTotalPrice: Float = 0f
    @OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false, fetch = FetchType.LAZY)
    var productCategoryProperty: ProductCategoryPropertyEntity = ProductCategoryPropertyEntity()
    @OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], fetch = FetchType.LAZY)
    var category: CategoryEntity = CategoryEntity()
    @Column(name = "images")
    var images: Array<String?> = arrayOf()
    @Column(name = "keywords", length = 65535, columnDefinition = "text")
    var keywords: String? = ""

    constructor() : super() {
    }

    fun convertToDto(): ProductDto {
        return ProductDto(id, productName, description, productModel, productArticul,
                productCount, productPrice, productExtra, productTotalPrice, isAvailable,
                productCategoryProperty?.convertToDto(), category?.convertToDto(), images, keywords)
    }
}

ProductCategoryPropertyEntity:

import ua.jdroidcoder.jdcshop.dto.ProductCategoryPropertyDto
import javax.persistence.*

@Entity
@Table(name = "product_category_property")
class ProductCategoryPropertyEntity : AbstractEntity<Long> {

    @OneToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false)
    var simpleProperties: MutableList<ProductPropertySimpleEntity> = ArrayList()

    @OneToMany(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false)
    var advancedProperties: MutableList<ProductPropertySimpleEntity> = ArrayList()

    constructor() : super() {
    }

    fun convertToDto(): ProductCategoryPropertyDto {
        val simple = ProductCategoryPropertyDto()
        simple.id = id
        simpleProperties?.forEach {
            simple.simpleProperties.add(it.convertToDto())
        }
        advancedProperties?.forEach {
            simple.advancedProperties.add(it.convertToDto())
        }
        return simple
    }
}

ProductPropertySimpleEntity:

import ua.jdroidcoder.jdcshop.dto.PropertySimpleDto
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table

@Entity
@Table(name = "product_property_simple")
class ProductPropertySimpleEntity : AbstractEntity<Long> {
    @Column(name = "property_name")
    var propertyName: String = ""

    @Column(name = "property_value")
    var propertyValue: String = ""

    @Column(name = "parent_id")
    var parentId: Long? = null

    @Column(name = "parent_id_in_category")
    var parentIdInCategory: Long? = null

    @Column(name = "id_in_category")
    var idInCategory: Long? = null

    constructor() : super() {
    }

    fun convertToDto(): PropertySimpleDto {
       return PropertySimpleDto(id!!,propertyName,parentId,propertyValue)
    }
}

When I try make select, I see:

Hibernate: select productent0_.id as id1_3_, productent0_.category_id as categor13_3_, productent0_.description as descript2_3_, productent0_.images as images3_3_, productent0_.is_available as is_avail4_3_, productent0_.keywords as keywords5_3_, productent0_.product_articul as product_6_3_, productent0_.product_category_property_id as product14_3_, productent0_.product_count as product_7_3_, productent0_.product_extra as product_8_3_, productent0_.product_model as product_9_3_, productent0_.product_name as product10_3_, productent0_.product_price as product11_3_, productent0_.product_total_price as product12_3_ from product productent0_
Hibernate: select categoryen0_.id as id1_0_0_, categoryen0_.category_name as category2_0_0_, categoryen0_.prom_category_id as prom_cat3_0_0_ from category categoryen0_ where categoryen0_.id=?
Hibernate: select productcat0_.id as id1_4_0_ from product_category_property productcat0_ where productcat0_.id=?
Hibernate: select simpleprop0_.product_category_property_entity_id as product_1_6_0_, simpleprop0_.simple_properties_id as simple_p2_6_0_, productpro1_.id as id1_7_1_, productpro1_.id_in_category as id_in_ca2_7_1_, productpro1_.parent_id as parent_i3_7_1_, productpro1_.parent_id_in_category as parent_i4_7_1_, productpro1_.property_name as property5_7_1_, productpro1_.property_value as property6_7_1_ from product_category_property_simple_properties simpleprop0_ inner join product_property_simple productpro1_ on simpleprop0_.simple_properties_id=productpro1_.id where simpleprop0_.product_category_property_entity_id=?
Hibernate: select advancedpr0_.product_category_property_entity_id as product_1_5_0_, advancedpr0_.advanced_properties_id as advanced2_5_0_, productpro1_.id as id1_7_1_, productpro1_.id_in_category as id_in_ca2_7_1_, productpro1_.parent_id as parent_i3_7_1_, productpro1_.parent_id_in_category as parent_i4_7_1_, productpro1_.property_name as property5_7_1_, productpro1_.property_value as property6_7_1_ from product_category_property_advanced_properties advancedpr0_ inner join product_property_simple productpro1_ on advancedpr0_.advanced_properties_id=productpro1_.id where advancedpr0_.product_category_property_entity_id=?

I know that it's happens via @OneToOne, but I can't seek solution ;(

I need receive only some fields like: productName, description, productModel, productArticul, productCount...

Thanks for help, guys!

Body:
@OneToOne is tricky if you allow null value.

JPA must try to access the record form the other table even if the property is signed with lazy-initialization, because it has to decide whether to set the property to null or a proxy-object.

It cannot set it null automatically, because there can be an associated object.
It cannot create the proxy-object automatically either, because there is no designated column in the table for the id of that property (Because one-to-one relationship is mapped by shared PK by default).

So the only way to decide if the associated entity does exist is trying to load its id from it's own table. If this query returns null then no associated entity, otherwise the JPA can create a proxy object from this id.

If you really need to avoid this extra request then add a foreign key to product_category_property table into the product table.

@OneToOne(cascade = [CascadeType.PERSIST, CascadeType.MERGE], orphanRemoval = false, fetch = FetchType.LAZY)
@JoinColumn(name='product_category_property')
var productCategoryProperty: ProductCategoryPropertyEntity = ProductCategoryPropertyEntity()

You can find further explanations in this topic.


来源: stackexchange

问:
Print the number of subarrays in an array having negative sum
```<code>import java.io.*;
import java.util.*;
public class Solution {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt(); //taking input number of elements in the array
        int[] a=new int[n];
        for(int i=0;i<n;i++){
            a[i]=scan.nextInt(); //taking input elements of the array
        }
        int count=0;
        //start point
        for(int i=0;i<n;i++){
            //end point
            for(int j=i;j<n;j++){
                for(int k=i;k<=j;k++){
                    int sum=0;
                    sum+=a[k];  //calculating the sum of subarray
                    if(sum<0)
                    count++;
                }
            }
        }
        System.out.println(count); //printing the no of negative sums
    }
}
</code>```

Here there are three nested loops first loop defines the starting position second loop defines the ending position and third loop is for iterating over the elements of the subsrray and calculating their sums and if the sum is less than zero then increment the count.But with this code I am getting wrong answer.

答:
Don't need the third loop</p>

```<code>int count = 0;
    for(int i = 0; i < n; i++) { // for start position
        int sum = 0;
        for(int j = i; j < n; j++) { // for end position
            sum += a[j];
            if(sum < 0) {
                count++;
            }
        }
    }
// output count
</code>```

ContentLicense: CC BY-SA 4.0

Body:
import java.io.*;
import java.util.*;
public class Solution {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        int n=scan.nextInt(); //taking input number of elements in the array
        int[] a=new int[n];
        for(int i=0;i<n;i++){
            a[i]=scan.nextInt(); //taking input elements of the array
        }
        int count=0;
        //start point
        for(int i=0;i<n;i++){
            //end point
            for(int j=i;j<n;j++){
                for(int k=i;k<=j;k++){
                    int sum=0;
                    sum+=a[k];  //calculating the sum of subarray
                    if(sum<0)
                    count++;
                }
            }
        }
        System.out.println(count); //printing the no of negative sums
    }
}

Here there are three nested loops first loop defines the starting position second loop defines the ending position and third loop is for iterating over the elements of the subsrray and calculating their sums and if the sum is less than zero then increment the count.But with this code I am getting wrong answer.

Body:
Don't need the third loop

int count = 0;
    for(int i = 0; i < n; i++) { // for start position
        int sum = 0;
        for(int j = i; j < n; j++) { // for end position
            sum += a[j];
            if(sum < 0) {
                count++;
            }
        }
    }
// output count


问:
How to make an expandable/collapsable section widget in Qt
I would like to create a custom widget in Qt with the following features:

It is a container

It may be populated with any Qt layout

It may be inside any Qt layout

A button allows to collapse/fold vertically the content, so only the button is visible, all the contained layout is invisible.

The previous button allows to expand/unfold it again to the size of the layout content.

The expanding/collapsing is based on sizes (not on show/hide) to allows animation.

Usable in QDesigner

To provide an idea, here is an image of a similar widget (not Qt):

I already have a frame that work correctly and is exposed in QDesigner. I need now to make it to extend/collapse, which does not seem so simple.

I tried to play with resize(), sizePolicy(), sizeHint() but that does not work:
When the frame is collapsed I got following values:

```<code>sizeHint: (500,20)
size    : (500,20)
closestAcceptableSize: (518,150)
Painted size: (518, 150)
</code>```

QLayout::closestAcceptableSize is not part of the widget so I cannot change it.

Any hint or/and code snippet to achieve that?

EDITED:
Here a simple example. I removed all except necessary.

main.cpp example

```<code>#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>

#include "section.hpp"

using namespace myWidgets;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Create the main Window
    QWidget window;
    window.resize(500,500);
    window.setStyleSheet("QPushButton:{background-color:rgba(128,128,128,192);}");

    // Create the main window layout
    QVBoxLayout topLayout(&window);
    QWidget *w1 = new QWidget();
    w1->setStyleSheet("background-color:rgba(128,128,128,192);");
    topLayout.addWidget(w1);

    Section section(&window);
    topLayout.addWidget(&section);

    QVBoxLayout inLayout(&section);
    QPushButton *button = new QPushButton();
    button->setMinimumHeight(100);
    inLayout.addWidget(button);

    QWidget *w2 = new QWidget();
    w2->setStyleSheet("background-color:rgba(128,128,128,192);");
    topLayout.addWidget(w2);

    window.show();

    return a.exec();
}
</code>```

Section.hpp

```<code>#ifndef SECTION_HPP
#define SECTION_HPP

#include <QPushButton> //for the expand/collapse button
#include <QtDesigner/QDesignerExportWidget>
#include <QLayout>
#include <QPainter>
#include <QPaintEvent>
#include <QDebug>

// Compatibility for noexcept, not supported in vsc++
#ifdef _MSC_VER
#define noexcept throw()
#endif

#if defined SECTION_BUILD
    #define SECTION_BUILD_DLL_SPEC Q_DECL_EXPORT
#elif defined SECTION_EXEC
    #define SECTION_BUILD_DLL_SPEC
#else
    #define SECTION_BUILD_DLL_SPEC Q_DECL_IMPORT
#endif

namespace myWidgets
{

class SECTION_BUILD_DLL_SPEC Section : public QWidget
{
    Q_OBJECT

    Q_PROPERTY( bool is_expanded MEMBER isExpanded)

public:
    // Constructor, standard
    explicit Section( QWidget *parent=0 ): QWidget(parent),
        expandButton(this)
    {
        expandButton.resize(20,20);
        expandButton.move(0,0);
        expandButton.connect(&expandButton, &QPushButton::clicked,
                             this, &Section::expandCollapseEvent);

        QMargins m= contentsMargins();
        m.setTop(m.top()+25);
        setContentsMargins(m);
        //setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Minimum);

    }

    virtual void expand( bool expanding ) noexcept
    {
        resize(sizeHint());
        isExpanded = expanding;
        updateGeometry();

qDebug() << (isExpanded? "expanded":"collapsed") << sizeHint() << QWidget::size() <<
            parentWidget()->layout()->closestAcceptableSize(this, size());
    }

    virtual QSize sizeHint() const noexcept override
    {
        if (isExpanded) return QSize(layout()->contentsRect().width(),
                                     layout()->contentsRect().height());
        else return QSize(layout()->contentsRect().width(), 20);
    }

    // Implement custom appearance
    virtual void paintEvent(QPaintEvent *e) noexcept override
    {
        (void) e; //TODO: remove
        QPainter p(this);
        p.setClipRect(e->rect());
        p.setRenderHint(QPainter::Antialiasing );
        p.fillRect(e->rect(), QColor(0,0,255,128));
    }

protected:

    // on click of the expandButton, collapse/expand this widget
    virtual void expandCollapseEvent() noexcept
    {
        expand(!isExpanded);
    }

    bool isExpanded = true; //whenever the section is collapsed(false) or expanded(true)
    QPushButton expandButton; //the expanding/collapsing button
};

}

#endif // SECTION_HPP
</code>```

答:
I built Python3/Qt5 styled example to test out a StyleSheet class I'm writing.
I also fixed an issue with size calculations that didn't consider size changes to the expander button.

I also changed the method to setLayout() to be consistent with Qt.

```<code>import sys
import inspect
import textwrap
from collections import OrderedDict, UserString
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *

class QStyleSheet(UserString):
    """
    Represent stylesheets as dictionary key value pairs.
    Update complex stylesheets easily modifying only the attributes you need
    Allow for attribute inheritance or defaulting of stylesheets.

    # TODO support [readOnly="true"] attribute-selectors
            QTextEdit, QListView  <-- you can have multiple classes.
            QCheckBox::indicator  <-- some psuedo classes have double colons
    """
    def __init__(self, cls=None, name=None, psuedo=None, **styles):
        """
        Arguments to the constructor allow you to default different properties of the CSS Class.
        Any argument defined here will be global to this StyleSheet and cannot be overidden later.

        :param cls: Default style prefix class to ``cls``
        :param name: Default object name to ``name`` (hashtag) is not needed.
        :param psuedo: Default psuedo class to ``psuedo``, example: ``:hover``
        """
        self.cls_scope = cls
        self.psuedo_scope = psuedo
        self.name_scope = name
        self._styles = OrderedDict() # we'll preserve the order of attributes given - python 3.6+
        if styles:
            self.setStylesDict(OrderedDict(styles))

    def _ident(self, cls=None, name=None, psuedo=None):

        # -- ensure value is of correct type ----------------------------------------
        if cls is not None and not inspect.isclass(cls):
            raise ValueError(f'cls must be None or a class object, got: {type(cls)}')

        if name is not None and not isinstance(name, str):
            raise ValueError(f'name must be None or a str, got: {type(name)}')

        if psuedo is not None and not isinstance(psuedo, str):
            raise ValueError(f'psuedo must be None or a str, got: {type(psuedo)}')

        # -- ensure not overiding defaults -------------------------------------------
        if cls is not None and self.cls_scope is not None:
            raise ValueError(f'cls was set in __init__, you cannot override it')

        if name is not None and self.name_scope is not None:
            raise ValueError(f'name was set in __init__, you cannot override it')

        if psuedo is not None and self.psuedo_scope is not None:
            raise ValueError(f'psuedo was set in __init__, you cannot override it')

        # -- apply defaults if set ---------------------------------------------------
        if cls is None and self.cls_scope is not None:
            cls = self.cls_scope

        if name is None and self.name_scope is not None:
            name = self.name_scope

        if psuedo is None and self.psuedo_scope is not None:
            psuedo = self.psuedo_scope

        # return a tuple that can be used as a dictionary key.
        ident = tuple([getattr(cls, '__name__', None), name or None, psuedo or None])
        return ident

    def _class_definition(self, ident):
        """Get the class definition string"""
        cls, name, psuedo = ident
        return '%s%s%s' % (cls or '', name or '', psuedo or '')

    def _fix_underscores(self, styles):
        return OrderedDict([(k.replace('_', '-'), v) for k,v in styles.items()])

    def setStylesStr(self, styles):
        """
        Parse styles from a string and set them on this object.
        """
        raise NotImplementedError()
        self._update()

    def setStylesDict(self, styles, cls=None, name=None, psuedo=None):
        """
        Set styles using a dictionary instead of keyword arguments
        """
        styles = self._fix_underscores(styles)
        if not isinstance(styles, dict):
            raise ValueError(f'`styles` must be dict, got: {type(styles)}')
        if not styles:
            raise ValueError('`styles` cannot be empty')

        ident = self._ident(cls, name, psuedo)
        stored = self._styles.get(ident, OrderedDict())
        stored.update(styles)
        self._styles[ident] = stored

        self._update()

    def setStyles(self, cls=None, name=None, psuedo=None, **styles):
        """
        Set or update styles according to the CSS Class definition provided by (cls, name, psuedo) using keyword-arguments.

        Any css attribute with a hyphen ``-`` character should be changed to an underscore ``_`` when passed as a keyword argument.

        Example::

            Lets suppose we want to create the css class:

                QFrame#BorderTest { background-color: white; margin:4px; border:1px solid #a5a5a5; border-radius: 10px;}

            >>> stylesheet.setStyle(cls=QFrameBorderTest, background_color='white', margin='4px', border_radius='10px')

            >>> print(stylesheet)

            QFrame#BorderTest { background-color: white; margin:4px; border:1px solid #a5a5a5; border-radius: 10px;}
        """
        styles = OrderedDict(styles)
        self.setStylesDict(styles=styles, cls=cls, name=name, psuedo=psuedo)

    def getStyles(self, cls=None, name=None, psuedo=None):
        """
        Return the dictionary representations of styles for the CSS Class definition provided by (cls, name, psuedo)

        :returns: styles dict (keys with hyphens)
        """
        ident = self._ident(cls, name, psuedo)
        return self._styles.get(ident)

    def getClassIdents(self):
        """Get all class identifier tuples"""
        return list(self._styles.keys())

    def getClassDefinitions(self):
        """Get all css class definitions, but not the css attributes/body"""
        return [self._class_definition(ident) for ident in self.getClassIdents()]

    def validate(self):
        """
        Validate all the styles and attributes on this class
        """
        raise NotImplementedError()

    def merge(self, stylesheet, overwrite=True):
        """
        Merge another QStyleSheet with this QStyleSheet.
        The QStyleSheet passed as an argument will be left un-modified.

        :param overwrite: if set to True the matching class definitions will be overwritten
                          with attributes and values from ``stylesheet``.
                          Otherwise, the css attributes will be updated from ``stylesheet``
        :type overwrite: QStyleSheet
        """
        for ident in stylesheet.getClassIdents():
            styles = stylesheet.getStyles(ident)
            cls, name, psuedo = ident
            self.setStylesDict(styles, cls=cls, name=name, psuedo=psuedo)

        self._update()

    def clear(self, cls=None, name=None, psuedo=None):
        """
        Clear styles matching the Class definition

        The style dictionary cleared will be returned

        None will be returned if nothing was cleared.
        """
        ident = self._ident(cls, name, psuedo)
        return self._styles.pop(ident, None)

    def _update(self):
        """Update the internal string representation"""
        stylesheet = []
        for ident, styles in self._styles.items():
            if not styles:
                continue
            css_cls = self._class_definition(ident)
            css_cls = css_cls + ' ' if css_cls else ''
            styles_str = '\n'.join([f'{k}: {v};' for k, v in styles.items()])

            styles_str = textwrap.indent(styles_str, ''.ljust(4))
            stylesheet.append('%s{\n%s\n}' % (css_cls, styles_str))

        self.data = '\n\n'.join(stylesheet)

class Expander(QWidget):
    def __init__(self, parent=None, title=None, animationDuration=200):
        super().__init__(parent=parent)

        self.animationDuration = animationDuration
        self.toggleAnimation = QtCore.QParallelAnimationGroup()
        self.contentArea = QScrollArea()
        self.headerLine = QFrame()
        self.toggleButton = QToolButton()
        self.mainLayout = QGridLayout()

        toggleButton = self.toggleButton
        self.toggleButtonQStyle = QStyleSheet(QToolButton, border='none')
        toggleButton.setStyleSheet(str(self.toggleButtonQStyle))
        toggleButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        toggleButton.setArrowType(QtCore.Qt.RightArrow)
        toggleButton.setText(title or '')
        toggleButton.setCheckable(True)
        toggleButton.setChecked(False)
        toggleButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        headerLine = self.headerLine
        self.headerLineQStyle = QStyleSheet(QFrame)
        headerLine.setFrameShape(QFrame.NoFrame)  # see: https://doc.qt.io/archives/qt-4.8/qframe.html#Shape-enum
        headerLine.setFrameShadow(QFrame.Plain)   # see: https://doc.qt.io/archives/qt-4.8/qframe.html#Shape-enum
        headerLine.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)

        self.contentAreaQStyle = QStyleSheet(QScrollArea, border='none')
        self.contentArea.setStyleSheet(str(self.contentAreaQStyle))
        self.contentArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # start out collapsed
        self.contentArea.setMaximumHeight(0)
        self.contentArea.setMinimumHeight(0)
        # let the entire widget grow and shrink with its content
        toggleAnimation = self.toggleAnimation
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"minimumHeight"))
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"maximumHeight"))
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self.contentArea, b"maximumHeight"))
        # don't waste space
        mainLayout = self.mainLayout
        mainLayout.setVerticalSpacing(0)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        row = 0
        mainLayout.addWidget(self.toggleButton, row, 0, 1, 1, QtCore.Qt.AlignLeft)
        mainLayout.addWidget(self.headerLine, row, 2, 1, 1)
        row += 1
        mainLayout.addWidget(self.contentArea, row, 0, 1, 3)
        super().setLayout(self.mainLayout)

        def start_animation(checked):
            arrow_type = QtCore.Qt.DownArrow if checked else QtCore.Qt.RightArrow
            direction = QtCore.QAbstractAnimation.Forward if checked else QtCore.QAbstractAnimation.Backward
            toggleButton.setArrowType(arrow_type)
            self.toggleAnimation.setDirection(direction)
            self.toggleAnimation.start()

        self.toggleButton.clicked.connect(start_animation)

    def setHeaderFrameStyles(self, styles):
        self._setWidgetStyles(self.headerLine, self.headerLineQStyle, styles)

    def setToggleButtonStyles(self, styles):
        self._setWidgetStyles(self.toggleButton, self.toggleButtonQStyle, styles)

    def setContentAreaStyles(self, styles):
        self._setWidgetStyles(self.contentArea, self.contentAreaQStyle, styles)

    def _setWidgetStyles(self, widget, qstylesheet, var):
        if isinstance(var, QStyleSheet):
            qstylesheet.merge(var)
            widget.setStyleSheet(str(qstylesheet))
        elif isinstance(var, dict):
            qstylesheet.setStylesDict(var)
            widget.setStyleSheet(str(qstylesheet))
        elif isinstance(var, str):
            widget.setStyleSheet(var)
        else:
            raise ValueError('invalid argument type: {type(var)}')

    def setLayout(self, contentLayout):
        """
        Set the layout container that you would like to expand/collapse.

        This should be called after all styles are set.
        """
        # Not sure if this is equivalent to self.contentArea.destroy()
        self.contentArea.destroy()
        self.contentArea.setLayout(contentLayout)
        collapsedHeight = self.toggleButton.sizeHint().height()
        contentHeight = contentLayout.sizeHint().height()
        for i in range(self.toggleAnimation.animationCount()-1):
            spoilerAnimation = self.toggleAnimation.animationAt(i)
            spoilerAnimation.setDuration(self.animationDuration)
            spoilerAnimation.setStartValue(collapsedHeight)
            spoilerAnimation.setEndValue(collapsedHeight + contentHeight)
        contentAnimation = self.toggleAnimation.animationAt(self.toggleAnimation.animationCount() - 1)
        contentAnimation.setDuration(self.animationDuration)
        contentAnimation.setStartValue(0)
        contentAnimation.setEndValue(contentHeight)

class MainWindow(QMainWindow):
    LIGHT_BLUE = '#148cc1'
    MED_BLUE = '#0c6a94'
    DARK_BLUE = '#0a3a6b'
    PALE_SALMON = '#fd756d'
    LIGHT_GREY = '#d2d5da'
    SLATE = '#525863'

    def __init__(self):
        super().__init__()

        self.WINDOW_STYLE = QStyleSheet(QMainWindow, background_color=self.SLATE)
        self.WINDOW_STYLE = str(self.WINDOW_STYLE)

        self.LABEL_STYLE = QStyleSheet(QLabel, color=self.DARK_BLUE, font_weight=400, font_size='9pt')
        self.LABEL_STYLE = str(self.LABEL_STYLE)

        # -- QPushButton stylesheet ---------------------
        self.BUTTON_STYLE = s1 = QStyleSheet()

        s1.setStyles(cls=QPushButton,
                    color='white',
                    font_weight=400,
                    border_style='solid',
                    padding='4px',
                    background_color=self.LIGHT_BLUE)

        s1.setStyles(cls=QPushButton, psuedo=':pressed',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':focus-pressed',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':disabled',
                    background_color=self.LIGHT_GREY)

        s1.setStyles(cls=QPushButton, psuedo=':checked',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':hover:!pressed:!checked',
                    background_color=self.MED_BLUE)
        self.BUTTON_STYLE = str(self.BUTTON_STYLE)

        self.BUTTON_GROUPBOX_STYLE = QStyleSheet(QGroupBox, border='none', font_weight='bold', color='white')
        self.BUTTON_GROUPBOX_STYLE = str(self.BUTTON_GROUPBOX_STYLE)

        self.TEXT_EDIT_STYLE = QStyleSheet(QTextEdit, color='white', border=f'1px solid {self.LIGHT_BLUE}', background_color=self.MED_BLUE)
        self.TEXT_EDIT_STYLE = str(self.TEXT_EDIT_STYLE)

        self.initUI()

    def initUI(self):
        contents_vbox = QVBoxLayout()
        label_box = QHBoxLayout()
        for text in ('hello', 'goodbye', 'adios'):
            lbl = QLabel(text)
            lbl.setStyleSheet(self.LABEL_STYLE)
            lbl.setAlignment(Qt.AlignCenter)
            label_box.addWidget(lbl)

        button_group = QButtonGroup()
        button_group.setExclusive(True)
        button_group.buttonClicked.connect(self._button_clicked)
        self.button_group = button_group

        button_hbox = QHBoxLayout()

        for _id, text in enumerate(('small', 'medium', 'large')):
            btn = QPushButton(text)
            btn.setCheckable(True)
            btn.setStyleSheet(self.BUTTON_STYLE)
            button_group.addButton(btn)
            button_group.setId(btn, _id)
            button_hbox.addWidget(btn)

        button_group.buttons()[0].toggle()

        text_area = QTextEdit()
        text_area.setPlaceholderText('Type a greeting here')
        text_area.setStyleSheet(self.TEXT_EDIT_STYLE)

        contents_vbox.addLayout(label_box)
        contents_vbox.addLayout(button_hbox)
        contents_vbox.addWidget(text_area)

        collapsible = Expander(self, 'Expander')
        collapsible.setToggleButtonStyles({'padding': '4px', 'background-color': 'white'})
        collapsible.setContentAreaStyles({'background-color': 'white'})
        collapsible.setLayout(contents_vbox)

        vbox = QVBoxLayout()
        vbox.addWidget(collapsible)
        vbox.setAlignment(Qt.AlignTop)
        widget = QWidget()
        widget.setLayout(vbox)

        self.setCentralWidget(widget)

        self.setGeometry(200, 200, 500, 400)
        self.setWindowTitle('Expander')
        self.setStyleSheet(self.WINDOW_STYLE)
        self.show()

    def _button_clicked(self, button):
        """
        For the toggle behavior of a QButtonGroup to work you must
        connect the clicked signal!
        """
        print('button-active', self.button_group.id(button))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())
</code>```

Body:
I would like to create a custom widget in Qt with the following features:

It is a container

It may be populated with any Qt layout

It may be inside any Qt layout

A button allows to collapse/fold vertically the content, so only the button is visible, all the contained layout is invisible.

The previous button allows to expand/unfold it again to the size of the layout content.

The expanding/collapsing is based on sizes (not on show/hide) to allows animation.

Usable in QDesigner

To provide an idea, here is an image of a similar widget (not Qt):

I already have a frame that work correctly and is exposed in QDesigner. I need now to make it to extend/collapse, which does not seem so simple.

I tried to play with resize(), sizePolicy(), sizeHint() but that does not work:
When the frame is collapsed I got following values:

sizeHint: (500,20)
size    : (500,20)
closestAcceptableSize: (518,150)
Painted size: (518, 150)

QLayout::closestAcceptableSize is not part of the widget so I cannot change it.

Any hint or/and code snippet to achieve that?

EDITED:
Here a simple example. I removed all except necessary.

main.cpp example

#include <QWidget>
#include <QPushButton>
#include <QVBoxLayout>

#include "section.hpp"

using namespace myWidgets;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // Create the main Window
    QWidget window;
    window.resize(500,500);
    window.setStyleSheet("QPushButton:{background-color:rgba(128,128,128,192);}");

    // Create the main window layout
    QVBoxLayout topLayout(&window);
    QWidget *w1 = new QWidget();
    w1->setStyleSheet("background-color:rgba(128,128,128,192);");
    topLayout.addWidget(w1);

    Section section(&window);
    topLayout.addWidget(&section);

    QVBoxLayout inLayout(&section);
    QPushButton *button = new QPushButton();
    button->setMinimumHeight(100);
    inLayout.addWidget(button);

    QWidget *w2 = new QWidget();
    w2->setStyleSheet("background-color:rgba(128,128,128,192);");
    topLayout.addWidget(w2);

    window.show();

    return a.exec();
}

Section.hpp

#ifndef SECTION_HPP
#define SECTION_HPP

#include <QPushButton> //for the expand/collapse button
#include <QtDesigner/QDesignerExportWidget>
#include <QLayout>
#include <QPainter>
#include <QPaintEvent>
#include <QDebug>

// Compatibility for noexcept, not supported in vsc++
#ifdef _MSC_VER
#define noexcept throw()
#endif

#if defined SECTION_BUILD
    #define SECTION_BUILD_DLL_SPEC Q_DECL_EXPORT
#elif defined SECTION_EXEC
    #define SECTION_BUILD_DLL_SPEC
#else
    #define SECTION_BUILD_DLL_SPEC Q_DECL_IMPORT
#endif

namespace myWidgets
{

class SECTION_BUILD_DLL_SPEC Section : public QWidget
{
    Q_OBJECT

    Q_PROPERTY( bool is_expanded MEMBER isExpanded)

public:
    // Constructor, standard
    explicit Section( QWidget *parent=0 ): QWidget(parent),
        expandButton(this)
    {
        expandButton.resize(20,20);
        expandButton.move(0,0);
        expandButton.connect(&expandButton, &QPushButton::clicked,
                             this, &Section::expandCollapseEvent);

        QMargins m= contentsMargins();
        m.setTop(m.top()+25);
        setContentsMargins(m);
        //setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Minimum);

    }

    virtual void expand( bool expanding ) noexcept
    {
        resize(sizeHint());
        isExpanded = expanding;
        updateGeometry();

qDebug() << (isExpanded? "expanded":"collapsed") << sizeHint() << QWidget::size() <<
            parentWidget()->layout()->closestAcceptableSize(this, size());
    }

    virtual QSize sizeHint() const noexcept override
    {
        if (isExpanded) return QSize(layout()->contentsRect().width(),
                                     layout()->contentsRect().height());
        else return QSize(layout()->contentsRect().width(), 20);
    }

    // Implement custom appearance
    virtual void paintEvent(QPaintEvent *e) noexcept override
    {
        (void) e; //TODO: remove
        QPainter p(this);
        p.setClipRect(e->rect());
        p.setRenderHint(QPainter::Antialiasing );
        p.fillRect(e->rect(), QColor(0,0,255,128));
    }

protected:

    // on click of the expandButton, collapse/expand this widget
    virtual void expandCollapseEvent() noexcept
    {
        expand(!isExpanded);
    }

    bool isExpanded = true; //whenever the section is collapsed(false) or expanded(true)
    QPushButton expandButton; //the expanding/collapsing button
};

}

#endif // SECTION_HPP

Body:
I built Python3/Qt5 styled example to test out a StyleSheet class I'm writing.
I also fixed an issue with size calculations that didn't consider size changes to the expander button.

I also changed the method to setLayout() to be consistent with Qt.

import sys
import inspect
import textwrap
from collections import OrderedDict, UserString
from PyQt5 import QtCore, QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import *

class QStyleSheet(UserString):
    """
    Represent stylesheets as dictionary key value pairs.
    Update complex stylesheets easily modifying only the attributes you need
    Allow for attribute inheritance or defaulting of stylesheets.

    # TODO support [readOnly="true"] attribute-selectors
            QTextEdit, QListView  <-- you can have multiple classes.
            QCheckBox::indicator  <-- some psuedo classes have double colons
    """
    def __init__(self, cls=None, name=None, psuedo=None, **styles):
        """
        Arguments to the constructor allow you to default different properties of the CSS Class.
        Any argument defined here will be global to this StyleSheet and cannot be overidden later.

        :param cls: Default style prefix class to ``cls``
        :param name: Default object name to ``name`` (hashtag) is not needed.
        :param psuedo: Default psuedo class to ``psuedo``, example: ``:hover``
        """
        self.cls_scope = cls
        self.psuedo_scope = psuedo
        self.name_scope = name
        self._styles = OrderedDict() # we'll preserve the order of attributes given - python 3.6+
        if styles:
            self.setStylesDict(OrderedDict(styles))

    def _ident(self, cls=None, name=None, psuedo=None):

        # -- ensure value is of correct type ----------------------------------------
        if cls is not None and not inspect.isclass(cls):
            raise ValueError(f'cls must be None or a class object, got: {type(cls)}')

        if name is not None and not isinstance(name, str):
            raise ValueError(f'name must be None or a str, got: {type(name)}')

        if psuedo is not None and not isinstance(psuedo, str):
            raise ValueError(f'psuedo must be None or a str, got: {type(psuedo)}')

        # -- ensure not overiding defaults -------------------------------------------
        if cls is not None and self.cls_scope is not None:
            raise ValueError(f'cls was set in __init__, you cannot override it')

        if name is not None and self.name_scope is not None:
            raise ValueError(f'name was set in __init__, you cannot override it')

        if psuedo is not None and self.psuedo_scope is not None:
            raise ValueError(f'psuedo was set in __init__, you cannot override it')

        # -- apply defaults if set ---------------------------------------------------
        if cls is None and self.cls_scope is not None:
            cls = self.cls_scope

        if name is None and self.name_scope is not None:
            name = self.name_scope

        if psuedo is None and self.psuedo_scope is not None:
            psuedo = self.psuedo_scope

        # return a tuple that can be used as a dictionary key.
        ident = tuple([getattr(cls, '__name__', None), name or None, psuedo or None])
        return ident

    def _class_definition(self, ident):
        """Get the class definition string"""
        cls, name, psuedo = ident
        return '%s%s%s' % (cls or '', name or '', psuedo or '')

    def _fix_underscores(self, styles):
        return OrderedDict([(k.replace('_', '-'), v) for k,v in styles.items()])

    def setStylesStr(self, styles):
        """
        Parse styles from a string and set them on this object.
        """
        raise NotImplementedError()
        self._update()

    def setStylesDict(self, styles, cls=None, name=None, psuedo=None):
        """
        Set styles using a dictionary instead of keyword arguments
        """
        styles = self._fix_underscores(styles)
        if not isinstance(styles, dict):
            raise ValueError(f'`styles` must be dict, got: {type(styles)}')
        if not styles:
            raise ValueError('`styles` cannot be empty')

        ident = self._ident(cls, name, psuedo)
        stored = self._styles.get(ident, OrderedDict())
        stored.update(styles)
        self._styles[ident] = stored

        self._update()

    def setStyles(self, cls=None, name=None, psuedo=None, **styles):
        """
        Set or update styles according to the CSS Class definition provided by (cls, name, psuedo) using keyword-arguments.

        Any css attribute with a hyphen ``-`` character should be changed to an underscore ``_`` when passed as a keyword argument.

        Example::

            Lets suppose we want to create the css class:

                QFrame#BorderTest { background-color: white; margin:4px; border:1px solid #a5a5a5; border-radius: 10px;}

            >>> stylesheet.setStyle(cls=QFrameBorderTest, background_color='white', margin='4px', border_radius='10px')

            >>> print(stylesheet)

            QFrame#BorderTest { background-color: white; margin:4px; border:1px solid #a5a5a5; border-radius: 10px;}
        """
        styles = OrderedDict(styles)
        self.setStylesDict(styles=styles, cls=cls, name=name, psuedo=psuedo)

    def getStyles(self, cls=None, name=None, psuedo=None):
        """
        Return the dictionary representations of styles for the CSS Class definition provided by (cls, name, psuedo)

        :returns: styles dict (keys with hyphens)
        """
        ident = self._ident(cls, name, psuedo)
        return self._styles.get(ident)

    def getClassIdents(self):
        """Get all class identifier tuples"""
        return list(self._styles.keys())

    def getClassDefinitions(self):
        """Get all css class definitions, but not the css attributes/body"""
        return [self._class_definition(ident) for ident in self.getClassIdents()]

    def validate(self):
        """
        Validate all the styles and attributes on this class
        """
        raise NotImplementedError()

    def merge(self, stylesheet, overwrite=True):
        """
        Merge another QStyleSheet with this QStyleSheet.
        The QStyleSheet passed as an argument will be left un-modified.

        :param overwrite: if set to True the matching class definitions will be overwritten
                          with attributes and values from ``stylesheet``.
                          Otherwise, the css attributes will be updated from ``stylesheet``
        :type overwrite: QStyleSheet
        """
        for ident in stylesheet.getClassIdents():
            styles = stylesheet.getStyles(ident)
            cls, name, psuedo = ident
            self.setStylesDict(styles, cls=cls, name=name, psuedo=psuedo)

        self._update()

    def clear(self, cls=None, name=None, psuedo=None):
        """
        Clear styles matching the Class definition

        The style dictionary cleared will be returned

        None will be returned if nothing was cleared.
        """
        ident = self._ident(cls, name, psuedo)
        return self._styles.pop(ident, None)

    def _update(self):
        """Update the internal string representation"""
        stylesheet = []
        for ident, styles in self._styles.items():
            if not styles:
                continue
            css_cls = self._class_definition(ident)
            css_cls = css_cls + ' ' if css_cls else ''
            styles_str = '\n'.join([f'{k}: {v};' for k, v in styles.items()])

            styles_str = textwrap.indent(styles_str, ''.ljust(4))
            stylesheet.append('%s{\n%s\n}' % (css_cls, styles_str))

        self.data = '\n\n'.join(stylesheet)

class Expander(QWidget):
    def __init__(self, parent=None, title=None, animationDuration=200):
        super().__init__(parent=parent)

        self.animationDuration = animationDuration
        self.toggleAnimation = QtCore.QParallelAnimationGroup()
        self.contentArea = QScrollArea()
        self.headerLine = QFrame()
        self.toggleButton = QToolButton()
        self.mainLayout = QGridLayout()

        toggleButton = self.toggleButton
        self.toggleButtonQStyle = QStyleSheet(QToolButton, border='none')
        toggleButton.setStyleSheet(str(self.toggleButtonQStyle))
        toggleButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
        toggleButton.setArrowType(QtCore.Qt.RightArrow)
        toggleButton.setText(title or '')
        toggleButton.setCheckable(True)
        toggleButton.setChecked(False)
        toggleButton.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

        headerLine = self.headerLine
        self.headerLineQStyle = QStyleSheet(QFrame)
        headerLine.setFrameShape(QFrame.NoFrame)  # see: https://doc.qt.io/archives/qt-4.8/qframe.html#Shape-enum
        headerLine.setFrameShadow(QFrame.Plain)   # see: https://doc.qt.io/archives/qt-4.8/qframe.html#Shape-enum
        headerLine.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)

        self.contentAreaQStyle = QStyleSheet(QScrollArea, border='none')
        self.contentArea.setStyleSheet(str(self.contentAreaQStyle))
        self.contentArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        # start out collapsed
        self.contentArea.setMaximumHeight(0)
        self.contentArea.setMinimumHeight(0)
        # let the entire widget grow and shrink with its content
        toggleAnimation = self.toggleAnimation
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"minimumHeight"))
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self, b"maximumHeight"))
        toggleAnimation.addAnimation(QtCore.QPropertyAnimation(self.contentArea, b"maximumHeight"))
        # don't waste space
        mainLayout = self.mainLayout
        mainLayout.setVerticalSpacing(0)
        mainLayout.setContentsMargins(0, 0, 0, 0)
        row = 0
        mainLayout.addWidget(self.toggleButton, row, 0, 1, 1, QtCore.Qt.AlignLeft)
        mainLayout.addWidget(self.headerLine, row, 2, 1, 1)
        row += 1
        mainLayout.addWidget(self.contentArea, row, 0, 1, 3)
        super().setLayout(self.mainLayout)

        def start_animation(checked):
            arrow_type = QtCore.Qt.DownArrow if checked else QtCore.Qt.RightArrow
            direction = QtCore.QAbstractAnimation.Forward if checked else QtCore.QAbstractAnimation.Backward
            toggleButton.setArrowType(arrow_type)
            self.toggleAnimation.setDirection(direction)
            self.toggleAnimation.start()

        self.toggleButton.clicked.connect(start_animation)

    def setHeaderFrameStyles(self, styles):
        self._setWidgetStyles(self.headerLine, self.headerLineQStyle, styles)

    def setToggleButtonStyles(self, styles):
        self._setWidgetStyles(self.toggleButton, self.toggleButtonQStyle, styles)

    def setContentAreaStyles(self, styles):
        self._setWidgetStyles(self.contentArea, self.contentAreaQStyle, styles)

    def _setWidgetStyles(self, widget, qstylesheet, var):
        if isinstance(var, QStyleSheet):
            qstylesheet.merge(var)
            widget.setStyleSheet(str(qstylesheet))
        elif isinstance(var, dict):
            qstylesheet.setStylesDict(var)
            widget.setStyleSheet(str(qstylesheet))
        elif isinstance(var, str):
            widget.setStyleSheet(var)
        else:
            raise ValueError('invalid argument type: {type(var)}')

    def setLayout(self, contentLayout):
        """
        Set the layout container that you would like to expand/collapse.

        This should be called after all styles are set.
        """
        # Not sure if this is equivalent to self.contentArea.destroy()
        self.contentArea.destroy()
        self.contentArea.setLayout(contentLayout)
        collapsedHeight = self.toggleButton.sizeHint().height()
        contentHeight = contentLayout.sizeHint().height()
        for i in range(self.toggleAnimation.animationCount()-1):
            spoilerAnimation = self.toggleAnimation.animationAt(i)
            spoilerAnimation.setDuration(self.animationDuration)
            spoilerAnimation.setStartValue(collapsedHeight)
            spoilerAnimation.setEndValue(collapsedHeight + contentHeight)
        contentAnimation = self.toggleAnimation.animationAt(self.toggleAnimation.animationCount() - 1)
        contentAnimation.setDuration(self.animationDuration)
        contentAnimation.setStartValue(0)
        contentAnimation.setEndValue(contentHeight)

class MainWindow(QMainWindow):
    LIGHT_BLUE = '#148cc1'
    MED_BLUE = '#0c6a94'
    DARK_BLUE = '#0a3a6b'
    PALE_SALMON = '#fd756d'
    LIGHT_GREY = '#d2d5da'
    SLATE = '#525863'

    def __init__(self):
        super().__init__()

        self.WINDOW_STYLE = QStyleSheet(QMainWindow, background_color=self.SLATE)
        self.WINDOW_STYLE = str(self.WINDOW_STYLE)

        self.LABEL_STYLE = QStyleSheet(QLabel, color=self.DARK_BLUE, font_weight=400, font_size='9pt')
        self.LABEL_STYLE = str(self.LABEL_STYLE)

        # -- QPushButton stylesheet ---------------------
        self.BUTTON_STYLE = s1 = QStyleSheet()

        s1.setStyles(cls=QPushButton,
                    color='white',
                    font_weight=400,
                    border_style='solid',
                    padding='4px',
                    background_color=self.LIGHT_BLUE)

        s1.setStyles(cls=QPushButton, psuedo=':pressed',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':focus-pressed',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':disabled',
                    background_color=self.LIGHT_GREY)

        s1.setStyles(cls=QPushButton, psuedo=':checked',
                    background_color=self.PALE_SALMON)

        s1.setStyles(cls=QPushButton, psuedo=':hover:!pressed:!checked',
                    background_color=self.MED_BLUE)
        self.BUTTON_STYLE = str(self.BUTTON_STYLE)

        self.BUTTON_GROUPBOX_STYLE = QStyleSheet(QGroupBox, border='none', font_weight='bold', color='white')
        self.BUTTON_GROUPBOX_STYLE = str(self.BUTTON_GROUPBOX_STYLE)

        self.TEXT_EDIT_STYLE = QStyleSheet(QTextEdit, color='white', border=f'1px solid {self.LIGHT_BLUE}', background_color=self.MED_BLUE)
        self.TEXT_EDIT_STYLE = str(self.TEXT_EDIT_STYLE)

        self.initUI()

    def initUI(self):
        contents_vbox = QVBoxLayout()
        label_box = QHBoxLayout()
        for text in ('hello', 'goodbye', 'adios'):
            lbl = QLabel(text)
            lbl.setStyleSheet(self.LABEL_STYLE)
            lbl.setAlignment(Qt.AlignCenter)
            label_box.addWidget(lbl)

        button_group = QButtonGroup()
        button_group.setExclusive(True)
        button_group.buttonClicked.connect(self._button_clicked)
        self.button_group = button_group

        button_hbox = QHBoxLayout()

        for _id, text in enumerate(('small', 'medium', 'large')):
            btn = QPushButton(text)
            btn.setCheckable(True)
            btn.setStyleSheet(self.BUTTON_STYLE)
            button_group.addButton(btn)
            button_group.setId(btn, _id)
            button_hbox.addWidget(btn)

        button_group.buttons()[0].toggle()

        text_area = QTextEdit()
        text_area.setPlaceholderText('Type a greeting here')
        text_area.setStyleSheet(self.TEXT_EDIT_STYLE)

        contents_vbox.addLayout(label_box)
        contents_vbox.addLayout(button_hbox)
        contents_vbox.addWidget(text_area)

        collapsible = Expander(self, 'Expander')
        collapsible.setToggleButtonStyles({'padding': '4px', 'background-color': 'white'})
        collapsible.setContentAreaStyles({'background-color': 'white'})
        collapsible.setLayout(contents_vbox)

        vbox = QVBoxLayout()
        vbox.addWidget(collapsible)
        vbox.setAlignment(Qt.AlignTop)
        widget = QWidget()
        widget.setLayout(vbox)

        self.setCentralWidget(widget)

        self.setGeometry(200, 200, 500, 400)
        self.setWindowTitle('Expander')
        self.setStyleSheet(self.WINDOW_STYLE)
        self.show()

    def _button_clicked(self, button):
        """
        For the toggle behavior of a QButtonGroup to work you must
        connect the clicked signal!
        """
        print('button-active', self.button_group.id(button))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec_())


问:
How to grab images in JPEG format in higher Fps from IP Camera
Hy Everyone!

I am having a problem in grabbing images from a Panasonic IP Camera in JPEG format infact the problem is with the fps because the fps is always remains 1 or 2 not more than it but infact camera supports upto 30 the cam model is Panasonic WV-SP302E i am using the following C# code to grab the image and display it in my winforms app

```<code>public partial class Form1 : Form
{
    // indicates wether to prevent caching in case of a proxy server or not
    private bool preventCaching = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.pictureBox1.Image = this.GetSingleFrame(@"http://ipaddress/SnapshotJPEG?Resolution=320x240&Quality=Standard");
        }
    }

    /// <summary>
    /// Get a single JPEG frame from the camera
    /// </summary>
    /// <param name="source">JPEG Stream source</param>
    /// <exception cref="WebException">If the IP camera is not receable or an error is occured</exception>
    /// <exception cref="Exception">If an unknown error occured</exception>
    public Bitmap GetSingleFrame(string source)
    {
        byte[] buffer = new byte[512 * 1024];   // buffer to read stream
        HttpWebRequest req = null;
        WebResponse resp = null;
        Stream stream = null;
        Random rnd = new Random((int)DateTime.Now.Ticks);

        try
        {
            int read, total = 0;

            // create request
            if (!preventCaching)
            {
                req = (HttpWebRequest)WebRequest.Create(source);
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(source + ((source.IndexOf('?') == -1) ? '?' : '&') + "fake=" + rnd.Next().ToString());
            }
            // set login and password
            req.Credentials = new NetworkCredential("root", "a");

            req.Timeout = -1;

            resp = req.GetResponse();

            // get response stream
            stream = resp.GetResponseStream();

            // loop
            do
            {
                read = stream.Read(buffer, total, 1024);

                total += read;
            }
            while (read != 0);

            Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

            return bmp;
        }
        catch (WebException ex)
        {
            string s = ex.ToString();
            return null;
        }
        catch (Exception ex)
        {
            string s = ex.ToString();
            return null;
        }
        finally
        {
            // abort request
            if (req != null)
            {
                req.Abort();
                req = null;
            }
            // close response stream
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            // close response
            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}
</code>```

I am even using the backgrounworker component to grab images in another thread but still 2 fps. Any idea how to increase the fps

答: Make sure you're lighting the scene adequately. The simple and somewhat inaccurate explanation is that digital cameras in auto exposure mode will wait until they have captured enough light, which in a dark scene (like a dark room at night) with an inefficient sensor will take a while. Try the camera in a lighter room, or outside in the daylight, and see if your frame rate improves.</p>

ContentLicense: CC BY-SA 3.0

Body:
Hy Everyone!

I am having a problem in grabbing images from a Panasonic IP Camera in JPEG format infact the problem is with the fps because the fps is always remains 1 or 2 not more than it but infact camera supports upto 30 the cam model is Panasonic WV-SP302E i am using the following C# code to grab the image and display it in my winforms app

public partial class Form1 : Form
{
    // indicates wether to prevent caching in case of a proxy server or not
    private bool preventCaching = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (true)
        {
            this.pictureBox1.Image = this.GetSingleFrame(@"http://ipaddress/SnapshotJPEG?Resolution=320x240&Quality=Standard");
        }
    }

    ///
    /// Get a single JPEG frame from the camera
    ///
    /// <param name="source">JPEG Stream source</param>
    /// <exception cref="WebException">If the IP camera is not receable or an error is occured</exception>
    /// <exception cref="Exception">If an unknown error occured</exception>
    public Bitmap GetSingleFrame(string source)
    {
        byte[] buffer = new byte[512 * 1024];   // buffer to read stream
        HttpWebRequest req = null;
        WebResponse resp = null;
        Stream stream = null;
        Random rnd = new Random((int)DateTime.Now.Ticks);

        try
        {
            int read, total = 0;

            // create request
            if (!preventCaching)
            {
                req = (HttpWebRequest)WebRequest.Create(source);
            }
            else
            {
                req = (HttpWebRequest)WebRequest.Create(source + ((source.IndexOf('?') == -1) ? '?' : '&') + "fake=" + rnd.Next().ToString());
            }
            // set login and password
            req.Credentials = new NetworkCredential("root", "a");

            req.Timeout = -1;

            resp = req.GetResponse();

            // get response stream
            stream = resp.GetResponseStream();

            // loop
            do
            {
                read = stream.Read(buffer, total, 1024);

                total += read;
            }
            while (read != 0);

            Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));

            return bmp;
        }
        catch (WebException ex)
        {
            string s = ex.ToString();
            return null;
        }
        catch (Exception ex)
        {
            string s = ex.ToString();
            return null;
        }
        finally
        {
            // abort request
            if (req != null)
            {
                req.Abort();
                req = null;
            }
            // close response stream
            if (stream != null)
            {
                stream.Close();
                stream = null;
            }
            // close response
            if (resp != null)
            {
                resp.Close();
                resp = null;
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.backgroundWorker1.RunWorkerAsync();
    }
}

I am even using the backgrounworker component to grab images in another thread but still 2 fps. Any idea how to increase the fps


问:
All post message is not showing with sql GROUP_CONCAT
I have this comments table to store all comments of each Post

```<code>comment_id    comment_message    posts_id   u_id   created
=============================================================
46            comments....       2          6      1559376498
47            comments....       2          6      1559376502
48            comments....       2          6      1559376598
</code>```

and comments_like table for each comment reaction (r_id)

```<code>cl_id    comment_id   posts_id    u_id   r_id   created
=============================================================
42       46           2           6      6     1559376598
43       47           2           6      2     1559376598
44       48           2           6      8     1559376598
45       46           2           1      2     1559376598
</code>```

Note: posts_id means posts table id, u_id means users table id, r_id means reaction id, comment_id means comment table id.

Now, I want to get all comments for a specific ID with a list of reaction id's and that reaction id which is given by the logged user.

For that, I am using the following SQL query but it's not showing my expected result :(

```<code>$query = $this->_db->_pdo->prepare("
            SELECT c.*, u.u_id, u.full_name, cl.r_id, GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
            FROM comments AS c
            LEFT JOIN users AS u ON c.u_id = u.u_id
            LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id
            WHERE c.posts_id = '$post_id'
            ORDER BY c.comment_id  ");
</code>```

Output of this query should be

1) all comments of specific post id ($post_id);

2) a list of reaction id's

3) reaction id of logged user.

答:
You're missing a GROUP BY clause on your query so it is grouping all the comments into one row; you need to group by c.comment_id. This should give you the results you want:

```<code>SELECT c.*, u.u_id, u.full_name, cl.r_id,
       GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
FROM comments AS c
LEFT JOIN users AS u ON c.u_id = u.u_id
LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id
WHERE c.posts_id = 2
GROUP BY c.comment_id
ORDER BY c.comment_id
</code>```

Output:

```<code>comment_id  comment_message posts_id    u_id    created     u_id    full_name   r_id
46          comments....    2           6       1559376498  6       Bill Jones  2,6
47          comments....    2           6       1559376502  6       Bill Jones  2
48          comments....    2           6       1559376598  6       Bill Jones  8
</code>```

Demo on dbfiddle

Body:
I have this comments table to store all comments of each Post

comment_id    comment_message    posts_id   u_id   created
=============================================================
46            comments....       2          6      1559376498
47            comments....       2          6      1559376502
48            comments....       2          6      1559376598

and comments_like table for each comment reaction (r_id)

cl_id    comment_id   posts_id    u_id   r_id   created
=============================================================
42       46           2           6      6     1559376598
43       47           2           6      2     1559376598
44       48           2           6      8     1559376598
45       46           2           1      2     1559376598

Note: posts_id means posts table id, u_id means users table id, r_id means reaction id, comment_id means comment table id.

Now, I want to get all comments for a specific ID with a list of reaction id's and that reaction id which is given by the logged user.

For that, I am using the following SQL query but it's not showing my expected result :(

$query = $this->_db->_pdo->prepare("
            SELECT c.*, u.u_id, u.full_name, cl.r_id, GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
            FROM comments AS c
            LEFT JOIN users AS u ON c.u_id = u.u_id
            LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id
            WHERE c.posts_id = '$post_id'
            ORDER BY c.comment_id  ");

Output of this query should be

1) all comments of specific post id ($post_id);

2) a list of reaction id's

3) reaction id of logged user.

Body:
You're missing a GROUP BY clause on your query so it is grouping all the comments into one row; you need to group by c.comment_id. This should give you the results you want:

SELECT c.*, u.u_id, u.full_name, cl.r_id,
       GROUP_CONCAT(cl.r_id ORDER BY cl.u_id) AS r_id
FROM comments AS c
LEFT JOIN users AS u ON c.u_id = u.u_id
LEFT JOIN comments_like AS cl ON cl.comment_id = c.comment_id
WHERE c.posts_id = 2
GROUP BY c.comment_id
ORDER BY c.comment_id

Output:

comment_id  comment_message posts_id    u_id    created     u_id    full_name   r_id
46          comments....    2           6       1559376498  6       Bill Jones  2,6
47          comments....    2           6       1559376502  6       Bill Jones  2
48          comments....    2           6       1559376598  6       Bill Jones  8

Demo on dbfiddle


问:
How to use purrr functions inside dplyr's select_if
I'm trying to find the shortest possible dplyr-purr combination.

Can I reduce the following statement which combines select_if() and map_df() ?

```<code>training.set.imputed %>%
  select_if(~sum(is.na(.))>0) %>% map_df(~sum(is.na(.)))
</code>```

I tried this:

```<code>training.set.imputed %>%
  select_if(~sum(is.na(.))>0, .funs = ~sum(is.na(.)))
</code>```

which throws this error:

Error: nm must be NULL or a character vector the same length as x

What does this mean?
Any ideas how to form the .funs term?

答:
I assume you want the number of NAs in each column keeping only columns that have at least 1 NA.

!) This avoids the code duplication and does not give an error.  First calculate the number of NAs in each column and then pick out the columns that are greater than 0.

```<code># test input - BOD comes with R
BOD[1,2] <- NA

BOD %>%
  map_df(~ sum(is.na(.))) %>%
  select_if(~ . > 0)
</code>```

giving:

```<code># A tibble: 1 x 1
  demand
   <int>
1      1
</code>```

2) This first selects out those columns with at least one NA and then finds the number of NAs in those columns giving the same result:

```<code>BOD %>%
  select_if(anyNA) %>%
  map_df(~ sum(is.na(.)))
</code>```

Body:
I'm trying to find the shortest possible dplyr-purr combination.

Can I reduce the following statement which combines select_if() and map_df() ?

training.set.imputed %>%
  select_if(~sum(is.na(.))>0) %>% map_df(~sum(is.na(.)))

I tried this:

training.set.imputed %>%
  select_if(~sum(is.na(.))>0, .funs = ~sum(is.na(.)))

which throws this error:

Error: nm must be NULL or a character vector the same length as x

What does this mean?
Any ideas how to form the .funs term?

Body:
I assume you want the number of NAs in each column keeping only columns that have at least 1 NA.

!) This avoids the code duplication and does not give an error.  First calculate the number of NAs in each column and then pick out the columns that are greater than 0.

# test input - BOD comes with R
BOD[1,2] <- NA

BOD %>%
  map_df(~ sum(is.na(.))) %>%
  select_if(~ . > 0)

giving:

# A tibble: 1 x 1
  demand
   <int>
1      1

2) This first selects out those columns with at least one NA and then finds the number of NAs in those columns giving the same result:

BOD %>%
  select_if(anyNA) %>%
  map_df(~ sum(is.na(.)))


问:
Sorting by multiple rules
Dictionary, which keys are three separated characters, and keys are different sized lists, use sort/sorted function to sort this dictionary by the length of values array. If the length of values array equal, sort it by the 3rd element(character) in key. If collision appears in this case as well, sort it by 2nd element in key in ascending order. Character size(upper/lower) does not matters.

I’ve managed to sort it by length of values but I can’t quite find solution how to find collision and using other two sorting rules.

x = {("a", "B", "b"):[2, 0], ("A", "c", "b"):[2,1], ("d", "a", "C"):[0, 0, 0],
     ("A", "A", "A"):[2], ("e", "e", "t"):[2, 3]}

sort1 = sorted(x.items(), key = lambda x: x[1].__len__())

input = {("a", "B", "b"):[2, 0], ("A", "c", "b"):[2,1], ("d", "a", "C"):[0, 0, 0],
         ("A", "A", "A"):[2], ("e", "e", "t"):[2, 3]}

expected_output = [(("A", "A", "A"):[2]),(("e", "e", "t"):[2, 3]),
                   (("A", "B", "b"):[2, 1]),(("a", "c", "b"):[2, 0]),
                   (("d", "a", "C"),[0, 0, 0])]
```

Title: Sorting by multiple rules

Body:
Can use a tuple for the key argument.

Here I use ord function to sort chars in descending mode.

x = {("a", "B", "b"):[2, 0], ("A", "c", "b"):[2,1], ("d", "a", "C"):[0, 0, 0], ("A", "A", "A"):[2], ("e", "e", "t"):[2, 3]}

sorted(x.items(), key=lambda x: (len(x[1]), -ord(x[0][2].lower()), x[0][1].lower()))

[(('A', 'A', 'A'), [2]),
 (('e', 'e', 't'), [2, 3]),
 (('a', 'B', 'b'), [2, 0]),
 (('A', 'c', 'b'), [2, 1]),
 (('d', 'a', 'C'), [0, 0, 0])]


问:
Why null is being display on the screen in an Angular 5 app?
I have simple template which display a value of a string:

```<code><span class="fax_number">{{company.fax}}</span>
</code>```

When the value empty, the screen display the string "null" instead of
empty string, this happen in many places in the application, is there
a good way to avoid this ?

答:
I think that best solution will be to use Safe navigation operator (?.)

Here how your code will looks like:

```<code><span class="fax_number">{{company?.fax}}</span>
</code>```

If you need more details: angular-docs.

Regards, Max

Body:
I have simple template which display a value of a string:

{{company.fax}}

When the value empty, the screen display the string "null" instead of
empty string, this happen in many places in the application, is there
a good way to avoid this ?

Body:
I think that best solution will be to use Safe navigation operator (?.)

Here how your code will looks like:

<span class="fax_number">{{company?.fax}}</span>

If you need more details: angular-docs.

Regards, Max


问:
css - targeting styles when overflow causing scrollbars
I have a div like this:

```<code><div id="test"></div>

#test {
  width:100px;
  overflow-y:auto;
}
</code>```

What I want to do is apply styles only when the overflow-y:auto has actually caused a scrollbar to appear.  Is there a way to do this via CSS/CSS3?

Thank you.

答:
No, CSS does not provide a way to apply styles based on other computed styles, as computed styles are up to the browser to settle. You'd have to do this with JavaScript instead, if it's possible with it (I'm guessing it is somehow but it's not hitting at my mind now) take a look at Joshua's answer.

By the way, the vertical scrollbar won't appear on your
 unless you give it a height. Without defining a height it'll always expand to fit its content, obviating the need for a scrollbar.

Body:
I have a div like this:

#test {
  width:100px;
  overflow-y:auto;
}

What I want to do is apply styles only when the overflow-y:auto has actually caused a scrollbar to appear.  Is there a way to do this via CSS/CSS3?

Thank you.

Body:
No, CSS does not provide a way to apply styles based on other computed styles, as computed styles are up to the browser to settle. You'd have to do this with JavaScript instead, if it's possible with it (I'm guessing it is somehow but it's not hitting at my mind now) take a look at Joshua's answer.

By the way, the vertical scrollbar won't appear on your <div> unless you give it a height. Without defining a height it'll always expand to fit its content, obviating the need for a scrollbar.


问:
Splitting Post Codes from a List
I have a got a list of Post Codes that I would like to return just the first part of it.

postcodes = list(df['postcode'][0:10])
```

<blockquote>
  <p>['EC4V 3EJ', 'SE1 9DW', 'W12 7EY', 'E14 9GA', 'E17 8ES', 'N10 3LR', 'W2 2RH', 'W3 7ST', 'W2 1PW', 'W4 5RG']</p>
</blockquote>

<pre class="lang-py prettyprint-override"><code>for p in postcodes:
    postcodes.append(p.split()[0])
postcodes
</code>```

I was expecting to get something like:

```<code>['EC4V', 'SE1', 'W12', 'E14' ...]
</code>```

but my kernel keeps looping and it doesn't return anything.

答:
You're looping over a list and appending to it in every iteration. Your loop will never stop (each member you loop over, you add another element to the list). You should use a list comprehension for your desired output:

In [1]: l = ['EC4V 3EJ', 'SE1 9DW', 'W12 7EY', 'E14 9GA', 'E17 8ES', 'N10 3LR', 'W2 2RH', 'W3 7ST', 'W2 1PW', 'W4 5RG
   ...: ']

In [2]: [p.split()[0] for p in l]
Out[2]: ['EC4V', 'SE1', 'W12', 'E14', 'E17', 'N10', 'W2', 'W3', 'W2', 'W4']
```

Title: Splitting Post Codes from a List

Body:
I have a got a list of Post Codes that I would like to return just the first part of it.

postcodes = list(df['postcode'][0:10])

['EC4V 3EJ', 'SE1 9DW', 'W12 7EY', 'E14 9GA', 'E17 8ES', 'N10 3LR', 'W2 2RH', 'W3 7ST', 'W2 1PW', 'W4 5RG']

for p in postcodes:
    postcodes.append(p.split()[0])
postcodes

I was expecting to get something like:

['EC4V', 'SE1', 'W12', 'E14' ...]

but my kernel keeps looping and it doesn't return anything.