问:
How do I save a FastAPI UploadFile which is a zip file to disk as .zip?
I'm uploading zip files as UploadFile via FastAPI and want to save them to the filesystem using async aiofiles like so:

```<code>async def upload(in_file: UploadFile = File(...)):
    filepath = /path/to/out_file.zip

    async with aiofiles.open(filepath, 'wb') as f:
        while buffer := await in_file.read(1024):
            await f.write(buffer)
        await f.close()
</code>```

The file is created at filepath, however it's 0B in size and unzip out_file.zip yields following error:

```<code>Archive: out_file.zip
    End-of-central-directory signature not found. Either this file is not
    a zipfile, or it constitutes one disk of a multi-part archive. In the
    latter case the central directory and zipfile comment will be found on
    the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of out_file.zip or out_file.zip.zip,
        and cannot find out_file.zip.ZIP, period.
</code>```

print(in_file.content_type) outputs application/x-zip-compressed and

python3 -m mimetypes out_file.zip yields type: application/zip encoding: None

I've spent way too much time on this inconvenience and tried several blocking alternatives like:

```<code>with open(filepath, "wb") as f:
    f.write(in_file.file.read())
    f.close()
</code>```

which all resulted in the same scenario. I'm trying to achieve this with .zip files right now but eventually I'm looking for a universal solution for binary files to save them as they come because I'm not processing any of the files, they just need to be stored.

If someone could point out to me what I'm missing that would be of great help.

Edit:
Before I try to write the file to my filesystem, I'm adding an Entry with some metadata to my database via Motor:

```<code>@router.post("/")
async def upload(in_file: UploadFile = File(...)):
    file_content = await in_file.read()
    file_db = {"name": in_file.filename, "size": len(file_content)}
    file_db_json = jsonable_encoder(file_db)
    added_file_db = await add_file(file_db_json)

    filepath = /path/to/out_file.zip
    async with aiofiles.open(filepath, 'wb') as f:
        while buffer := await in_file.read(1024):
            await f.write(buffer)

    return ResponseModel(added_file_db, "upload successful")
</code>```

The return in upload() confirms the upload was successful, metadata is added to the database, the file is created in my filesystem but broken as described above. I don't know how any of this would interfere with writing the file contents to my disk but maybe I'm wrong.

答:
You can save the file using aiofiles as shown below (take a look at this answer for more details):

from fastapi import FastAPI, File, UploadFile, status
from fastapi.exceptions import HTTPException
import aiofiles
import os

CHUNK_SIZE = 1024 * 1024  # adjust the chunk size as desired
app = FastAPI()

@app.post("/upload")
async def upload(file: UploadFile = File(...)):
    try:
        filepath = os.path.join('./', os.path.basename(file.filename))
        async with aiofiles.open(filepath, 'wb') as f:
            while chunk := await file.read(CHUNK_SIZE):
                await f.write(chunk)
    except Exception:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail='There was an error uploading the file')
    finally:
        await file.close()

    return {"message": f"Successfuly uploaded {file.filename}"}
```
<h2>Update</h2>
<p>The recent edit in your question shows that you have already read the file contents at this line: <code>file_content = await in_file.read()</code>; hence, attempting to read the file contents again using <code>await in_file.read(1024)</code> would result in reading zero bytes. Thus, you can either add the metadata to the database after reading and saving the file (you can use a varibale to keep the total file length e.g.,<code>total_len += len(buffer)</code>), or just write the <code>file_content</code> to the local file, as shown below:</p>
<pre class="lang-py prettyprint-override"><code>async def upload(file: UploadFile = File(...)):
    ...
    async with aiofiles.open(filepath, 'wb') as f:
        await f.write(file_content)
</code>```

Update 2

For the sake of completeness, I should also mention that there is an internal "cursor" (or "file pointer") denoting the position from which the file contents will be read (or written). When calling .read() reads all the way to the end of the buffer, leaving zero bytes beyond the cursor. Thus, one could use the .seek() method to set the current position of the cursor to 0 (i.e., rewinding the cursor to the start of the file). As per FastAPI documentation:

seek(offset): Goes to the byte position offset (int) in the file.

E.g., await myfile.seek(0) would go to the start of the file.

This is especially useful if you run await myfile.read() once and then need to read the contents again.

Body:
I'm uploading zip files as UploadFile via FastAPI and want to save them to the filesystem using async aiofiles like so:

async def upload(in_file: UploadFile = File(...)):
    filepath = /path/to/out_file.zip

    async with aiofiles.open(filepath, 'wb') as f:
        while buffer := await in_file.read(1024):
            await f.write(buffer)
        await f.close()

The file is created at filepath, however it's 0B in size and unzip out_file.zip yields following error:

Archive: out_file.zip
    End-of-central-directory signature not found. Either this file is not
    a zipfile, or it constitutes one disk of a multi-part archive. In the
    latter case the central directory and zipfile comment will be found on
    the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of out_file.zip or out_file.zip.zip,
        and cannot find out_file.zip.ZIP, period.

print(in_file.content_type) outputs application/x-zip-compressed and

python3 -m mimetypes out_file.zip yields type: application/zip encoding: None

I've spent way too much time on this inconvenience and tried several blocking alternatives like:

with open(filepath, "wb") as f:
    f.write(in_file.file.read())
    f.close()

which all resulted in the same scenario. I'm trying to achieve this with .zip files right now but eventually I'm looking for a universal solution for binary files to save them as they come because I'm not processing any of the files, they just need to be stored.

If someone could point out to me what I'm missing that would be of great help.

Edit:
Before I try to write the file to my filesystem, I'm adding an Entry with some metadata to my database via Motor:

@router.post("/")
async def upload(in_file: UploadFile = File(...)):
    file_content = await in_file.read()
    file_db = {"name": in_file.filename, "size": len(file_content)}
    file_db_json = jsonable_encoder(file_db)
    added_file_db = await add_file(file_db_json)

    filepath = /path/to/out_file.zip
    async with aiofiles.open(filepath, 'wb') as f:
        while buffer := await in_file.read(1024):
            await f.write(buffer)

    return ResponseModel(added_file_db, "upload successful")

The return in upload() confirms the upload was successful, metadata is added to the database, the file is created in my filesystem but broken as described above. I don't know how any of this would interfere with writing the file contents to my disk but maybe I'm wrong.

Body:
You can save the file using aiofiles as shown below (take a look at this answer for more details):

from fastapi import FastAPI, File, UploadFile, status
from fastapi.exceptions import HTTPException
import aiofiles
import os

CHUNK_SIZE = 1024 * 1024  # adjust the chunk size as desired
app = FastAPI()

@app.post("/upload")
async def upload(file: UploadFile = File(...)):
    try:
        filepath = os.path.join('./', os.path.basename(file.filename))
        async with aiofiles.open(filepath, 'wb') as f:
            while chunk := await file.read(CHUNK_SIZE):
                await f.write(chunk)
    except Exception:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail='There was an error uploading the file')
    finally:
        await file.close()

    return {"message": f"Successfuly uploaded {file.filename}"}

Update

The recent edit in your question shows that you have already read the file contents at this line: file_content = await in_file.read(); hence, attempting to read the file contents again using await in_file.read(1024) would result in reading zero bytes. Thus, you can either add the metadata to the database after reading and saving the file (you can use a varibale to keep the total file length e.g.,total_len += len(buffer)), or just write the file_content to the local file, as shown below:

async def upload(file: UploadFile = File(...)):
    ...
    async with aiofiles.open(filepath, 'wb') as f:
        await f.write(file_content)

Update 2

For the sake of completeness, I should also mention that there is an internal "cursor" (or "file pointer") denoting the position from which the file contents will be read (or written). When calling .read() reads all the way to the end of the buffer, leaving zero bytes beyond the cursor. Thus, one could use the .seek() method to set the current position of the cursor to 0 (i.e., rewinding the cursor to the start of the file). As per FastAPI documentation:

seek(offset): Goes to the byte position offset (int) in the file.

E.g., await myfile.seek(0) would go to the start of the file.

This is especially useful if you run await myfile.read() once and then need to read the contents again.


来源: stackexchange

问:
PHP change a function from from loops to recursion
I have the following JSON object:

```<code>{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}
</code>```

I want to collect all the label and value attributes and store them in an array, so I created the following function:

```<code>public function collectValues($arr){
    $finalValues = [];
    foreach($arr as $key => $element){
        if($key=='block'){
            foreach($element as $key2 => $block){
                if($key2=='descends'){
                    foreach($block as $key3 => $node_block){
                        if($key3=='descends'){
                            foreach($node_block as $key4 => $anotherNode){

                                if($key4 == 'descends'){
                                    foreach($anotherNode as $finalNode){
                                        $finalValues [] = array('lable'=>$finalNode->label, 'value' =>$finalNode->value);
                                    }

                                }
                            }

                        }
                        else{
                            $finalValues [] = array('lable' => $node_block->label, 'value' => $node_block->value);
                        }
                    }
                }
            }

            $finalValues [] = array('lable'=> $element->label, 'value' => $element->value);
        }
    }

    return $finalValues;
}
</code>```

The function works and I get the following:

```<code>[
    {
        "lable": 2,
        "value": false
    },
    {
        "lable": 1,
        "value": 3
    },
    {
        "lable": 2,
        "value": 2
    },
    {
        "lable": 1,
        "value": true
    }
]
</code>```

The problem is that the JSON object can contain more descends like:

```<code>{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "operation":"sum",
                        "descends":[
                            {
                                "label":2,
                                "value":false
                            }
                        ],
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ],
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}
</code>```

This means I will have to add more foreach loops. A good way to handle such a situation is by using recursive. How can I transform the function above into a recursive one?

答:
Your looped function does not make sense to change. Easier to rewrite from scratch
Here is my use case for recursion. Maybe there is an easier option, but I didn’t chase optimization</p>
```<code>$array = json_decode($json, true); //in $json your JSON)
$result = []; // array for result
checkLabel($array, $result);
print_r($result);

function checkLabel(array $array, &$result){
    //first check every element on nested array
    foreach ($array as $key => $value){

        if (is_array($value)) {
            //if found call recursive function
            checkLabel($value, $result);
        }
    }
    //then check 'label' key.. its mean we have attribute
    if (array_key_exists('label', $array)) {
        //save it
        $result[] = [
            'label' => $array['label'],
            'value' => $array['value']??'' //if have label but without value)
        ];
    }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have the following JSON object:

{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}

I want to collect all the label and value attributes and store them in an array, so I created the following function:

public function collectValues($arr){
    $finalValues = [];
    foreach($arr as $key => $element){
        if($key=='block'){
            foreach($element as $key2 => $block){
                if($key2=='descends'){
                    foreach($block as $key3 => $node_block){
                        if($key3=='descends'){
                            foreach($node_block as $key4 => $anotherNode){

                                if($key4 == 'descends'){
                                    foreach($anotherNode as $finalNode){
                                        $finalValues [] = array('lable'=>$finalNode->label, 'value' =>$finalNode->value);
                                    }

                                }
                            }

                        }
                        else{
                            $finalValues [] = array('lable' => $node_block->label, 'value' => $node_block->value);
                        }
                    }
                }
            }

            $finalValues [] = array('lable'=> $element->label, 'value' => $element->value);
        }
    }

    return $finalValues;
}

The function works and I get the following:

[
    {
        "lable": 2,
        "value": false
    },
    {
        "lable": 1,
        "value": 3
    },
    {
        "lable": 2,
        "value": 2
    },
    {
        "lable": 1,
        "value": true
    }
]

The problem is that the JSON object can contain more descends like:

{
    "id": 1,
    "name": null,
    "block": {
        "type": "none",
        "descends": [
            {
                "operation":"sum",
                "descends":[
                    {
                        "operation":"sum",
                        "descends":[
                            {
                                "label":2,
                                "value":false
                            }
                        ],
                        "label":2,
                        "value":false
                    }
                ]
            },
            {
                "operation":"sum",
                "descends":[
                    {
                        "label":2,
                        "value":false
                    }
                ],
                "label": 1,
                "value": 3,
            },
            {
                "label": 2,
                "value": 2
            }
        ],
        "label": 1,
        "value": true
    }
}

This means I will have to add more foreach loops. A good way to handle such a situation is by using recursive. How can I transform the function above into a recursive one?

Body:
Your looped function does not make sense to change. Easier to rewrite from scratch
Here is my use case for recursion. Maybe there is an easier option, but I didn’t chase optimization

$array = json_decode($json, true); //in $json your JSON)
$result = []; // array for result
checkLabel($array, $result);
print_r($result);

function checkLabel(array $array, &$result){
    //first check every element on nested array
    foreach ($array as $key => $value){

        if (is_array($value)) {
            //if found call recursive function
            checkLabel($value, $result);
        }
    }
    //then check 'label' key.. its mean we have attribute
    if (array_key_exists('label', $array)) {
        //save it
        $result[] = [
            'label' => $array['label'],
            'value' => $array['value']??'' //if have label but without value)
        ];
    }
}


问:
Need a simple explanation of the inject method
```<code>[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10
</code>```

I'm looking at this code but my brain is not registering how the number 10 can become the result. Would someone mind explaining what's happening here?

答:
Inject applies the block

```<code>result + element
</code>```

to each item in the array. For the next item ("element"), the value returned from the block is "result". The way you've called it (with a parameter), "result" starts with the value of that parameter. So the effect is adding the elements up.

OwnerDisplayName: hightide

ContentLicense: CC BY-SA 2.5

Body:
[1, 2, 3, 4].inject(0) { |result, element| result + element } # => 10

I'm looking at this code but my brain is not registering how the number 10 can become the result. Would someone mind explaining what's happening here?

Body:
Inject applies the block

result + element

to each item in the array. For the next item ("element"), the value returned from the block is "result". The way you've called it (with a parameter), "result" starts with the value of that parameter. So the effect is adding the elements up.

OwnerDisplayName: Sam Hoice

LastEditorDisplayName: Sam Hoice


问:
Is there a way to check if a class is convertible to some template instantiation?

The question

Here some code

struct Base
{
    int SomeMethod(const Base&);
    template <class T> int SomeMethod(const T&);
};

template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
};

struct tag {};
struct another_tag {};

struct ImplicitOpToAnotherTagInstantiation { operator Derived<another_tag>() const; };
```
<p>Is there something (<code>Derived::SomeMethod</code> overload) that i can write in <code>Derived</code> without touching the <code>Base</code>, that will cause a compiler error in the next code?</p>
<pre class="lang-cpp prettyprint-override"><code>Derived<tag>{}.SomeMethod(ImplicitOpToAnotherTagInstantiation {});
</code>```

Next code should be correct

struct ImplicitOpToBase { operator Base() const; };

Derived<tag>{}.SomeMethod(Derived<tag>{});
Derived<tag>{}.SomeMethod(Base{});
Derived<tag>{}.SomeMethod(ImplicitOpToBase{});
// Derived<tag>{}.SomeMethod(Derived<another_tag>{}); compiler error!
```
<h2>What have I tried</h2>
<ul>
<li>First thought was to do something like this:</li>
</ul>
<pre class="lang-cpp prettyprint-override"><code>template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
    template <class T, class OtherTag> std::enable_if_t<!std::is_same<Tag, OtherTag> && std::is_convertible<Tag, Derived<OtherTag>>> SomeMethod(T) = delete;
};
</code>```

But it doesn't work because there is no way for compiler to deduce OtherTag, without explicit instantiation like this

Derived<tag>{}.SomeMethod<ImplicitOpToAnotherTagInstantiation, another_tag>(); // error: deleted function!
```
<ul>
<li>Second thought:</li>
</ul>
<pre class="lang-cpp prettyprint-override"><code>template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
    template <class T> std::enable_if_t<!std::is_same<T, Derived> && std::is_convertible<T, Base>> SomeMethod(T) = delete;
};
</code>```

But next code results in compiler error, when shouldn't:

Derived<tag>{}.SomeMethod(ImplicitOpToBase{});
```
<h2>Main usage</h2>
<p>I am trying to create some kind of a strong typedef for <code>std::string</code> where <code>Base</code> is <code>std::string</code>, <code>Derived</code> is my <code>TaggedString</code>, <code>SomeMethod</code> is <code>std::string::assign</code>. I want to disable <code>assign</code> method with types of another tag and I have some difficulties explained in the question. For the sake of the reader i am omitting the fact, that <code>TaggedString</code> is implicitly convertible to <code>std::string_view</code>.</p>
<pre class="lang-cpp prettyprint-override"><code>template <class Tag> struct TaggedString : std::string
{
    using std::string::assign;
    TaggedString& assign(const TaggedString& other) { std::string::assign(other); return *this; }
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> assign(TaggedString<OtherTag>) = delete;
};
</code>```

Here is something to play with.

答:
No. There's an infinite set of possible conversions, even an infinite set of conversions to Derived<SomeUnknownType>. Your compiler cannot test every possible type T to see if ImplicitOpToAnotherTagInstantiation is perhaps convertible to Derived<T>.

It could test a finite set, if you provide that. But you only have tag, a type to exclude. An infinite set of types minus one type is still an infinite set of types.

Body:
The question

Here some code

struct Base
{
    int SomeMethod(const Base&);
    template <class T> int SomeMethod(const T&);
};

template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
};

struct tag {};
struct another_tag {};

struct ImplicitOpToAnotherTagInstantiation { operator Derived<another_tag>() const; };

Is there something (Derived::SomeMethod overload) that i can write in Derived without touching the Base, that will cause a compiler error in the next code?

Derived<tag>{}.SomeMethod(ImplicitOpToAnotherTagInstantiation {});

Next code should be correct

struct ImplicitOpToBase { operator Base() const; };

Derived<tag>{}.SomeMethod(Derived<tag>{});
Derived<tag>{}.SomeMethod(Base{});
Derived<tag>{}.SomeMethod(ImplicitOpToBase{});
// Derived<tag>{}.SomeMethod(Derived<another_tag>{}); compiler error!

What have I tried

First thought was to do something like this:

template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
    template <class T, class OtherTag> std::enable_if_t<!std::is_same<Tag, OtherTag> && std::is_convertible<Tag, Derived<OtherTag>>> SomeMethod(T) = delete;
};

But it doesn't work because there is no way for compiler to deduce OtherTag, without explicit instantiation like this

Derived<tag>{}.SomeMethod<ImplicitOpToAnotherTagInstantiation, another_tag>(); // error: deleted function!

Second thought:

template <class Tag> struct Derived : Base
{
    using Base::SomeMethod;
    int SomeMethod(const Derived&);
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> SomeMethod(Derived<OtherTag>) = delete;
    template <class T> std::enable_if_t<!std::is_same<T, Derived> && std::is_convertible<T, Base>> SomeMethod(T) = delete;
};

But next code results in compiler error, when shouldn't:

Derived<tag>{}.SomeMethod(ImplicitOpToBase{});

Main usage

I am trying to create some kind of a strong typedef for std::string where Base is std::string, Derived is my TaggedString, SomeMethod is std::string::assign. I want to disable assign method with types of another tag and I have some difficulties explained in the question. For the sake of the reader i am omitting the fact, that TaggedString is implicitly convertible to std::string_view.

template <class Tag> struct TaggedString : std::string
{
    using std::string::assign;
    TaggedString& assign(const TaggedString& other) { std::string::assign(other); return *this; }
    template <class OtherTag> std::enable_if_t<!std::is_same_v<Tag, OtherTag>> assign(TaggedString<OtherTag>) = delete;
};

Here is something to play with.


问:
How to combine 2 or more objects in a list based on certain fields of those objects
I'm sorry if the title sounds vague.

I have an object -

```<code>    public class AccountInfo {
        private String accountId;
        private Double vat;
        private Double totalFee;
        private Date invoiceDate;
    }
</code>```

and there is a list of these objects-

```<code>List<AccountInfo> AccountInfoLst;
</code>```

I want to manipulate this list by combining objects with the same accountId by adding up the vat and totalFee fields, provided they have the same invoiceDate as well.

If two objects have the same accountId but different invoiceDate, they shouldn't be combined.

答:
If you want to do it utilizing Streams one of the possible ways will be to collect the data into the Map, using as a key an object that combines accountId and invoiceDate.

All accounts mapped to the same key will be merged.

Accounts that differ in accountId or invoiceDate will remain intact.

Another option will be to create a nested map. In which accountId will be used as a key, a value will be a map which will use in turn invoiceDate as a key and a value will be an AccountInfo.

```<code>    public static void main(String[] args) {
        List<AccountInfo> result = List.of(
                    new AccountInfo("123", 80., 180., LocalDate.now()),
                    new AccountInfo("123", 120., 590., LocalDate.now()),
                    new AccountInfo("123", 30., 120., LocalDate.now().minusDays(3))
                )
                .stream()
                .collect(Collectors.toMap(
                        AccountWrapper::new,
                        UnaryOperator.identity(),
                        (acc1, acc2) -> new AccountInfo(
                                acc1.getAccountId(),
                                acc1.getVat() + acc2.getVat(),
                                acc1.getTotalFee() + acc2.getTotalFee(),
                                acc1.getInvoiceDate())
                ))
                .values().stream()
                .collect(Collectors.toList());

        result.forEach(System.out::println);
    }

    public record AccountWrapper(String accountId, LocalDate invoiceDate) {
        public AccountWrapper(AccountInfo info) {
            this(info.getAccountId(), info.getInvoiceDate());
        }
    }
</code>```

If you are using Java 15 or earlier AccountWrapper could be implemented as a regular class:

```<code>    public class AccountWrapper {
        private final String accountId;
        private final LocalDate invoiceDate;

        public AccountWrapper(AccountInfo info) {
            this.accountId = info.getAccountId();
            this.invoiceDate = info.getInvoiceDate();
        }

        @Override
        public int hashCode() {
            return Objects.hash(accountId, invoiceDate);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            AccountWrapper other = (AccountWrapper) o;
            return accountId.equals(other.accountId) && invoiceDate.equals(other.invoiceDate);
        }
    }
</code>```

Version with a nested map, no auxiliary objects are needed

```<code>        List<AccountInfo> result = List.of(
                        new AccountInfo("123", 80., 180., LocalDate.now()),
                        new AccountInfo("123", 120., 590., LocalDate.now()),
                        new AccountInfo("123", 30., 120., LocalDate.now().minusDays(3))
                )
                .stream()
                .collect(Collectors.groupingBy(
                        AccountInfo::getAccountId,
                        Collectors.toMap(
                                AccountInfo::getInvoiceDate,
                                UnaryOperator.identity(),
                                (acc1, acc2) -> new AccountInfo(
                                    acc1.getAccountId(),
                                    acc1.getVat() + acc2.getVat(),
                                    acc1.getTotalFee() + acc2.getTotalFee(),
                                    acc1.getInvoiceDate())
                        )))
                .values().stream()
                .flatMap(map -> map.values().stream())
                .collect(Collectors.toList());

        result.forEach(System.out::println);
</code>```

output

```<code>AccountInfo{accountId='123', vat=200.0, totalFee=770.0, invoiceDate=2022-02-09}
AccountInfo{accountId='123', vat=30.0, totalFee=120.0, invoiceDate=2022-02-06}
</code>```

Body:
I'm sorry if the title sounds vague.

I have an object -

    public class AccountInfo {
        private String accountId;
        private Double vat;
        private Double totalFee;
        private Date invoiceDate;
    }

and there is a list of these objects-

List<AccountInfo> AccountInfoLst;

I want to manipulate this list by combining objects with the same accountId by adding up the vat and totalFee fields, provided they have the same invoiceDate as well.

If two objects have the same accountId but different invoiceDate, they shouldn't be combined.

Body:
If you want to do it utilizing Streams one of the possible ways will be to collect the data into the Map, using as a key an object that combines accountId and invoiceDate.

All accounts mapped to the same key will be merged.

Accounts that differ in accountId or invoiceDate will remain intact.

Another option will be to create a nested map. In which accountId will be used as a key, a value will be a map which will use in turn invoiceDate as a key and a value will be an AccountInfo.

    public static void main(String[] args) {
        List<AccountInfo> result = List.of(
                    new AccountInfo("123", 80., 180., LocalDate.now()),
                    new AccountInfo("123", 120., 590., LocalDate.now()),
                    new AccountInfo("123", 30., 120., LocalDate.now().minusDays(3))
                )
                .stream()
                .collect(Collectors.toMap(
                        AccountWrapper::new,
                        UnaryOperator.identity(),
                        (acc1, acc2) -> new AccountInfo(
                                acc1.getAccountId(),
                                acc1.getVat() + acc2.getVat(),
                                acc1.getTotalFee() + acc2.getTotalFee(),
                                acc1.getInvoiceDate())
                ))
                .values().stream()
                .collect(Collectors.toList());

        result.forEach(System.out::println);
    }

    public record AccountWrapper(String accountId, LocalDate invoiceDate) {
        public AccountWrapper(AccountInfo info) {
            this(info.getAccountId(), info.getInvoiceDate());
        }
    }

If you are using Java 15 or earlier AccountWrapper could be implemented as a regular class:

    public class AccountWrapper {
        private final String accountId;
        private final LocalDate invoiceDate;

        public AccountWrapper(AccountInfo info) {
            this.accountId = info.getAccountId();
            this.invoiceDate = info.getInvoiceDate();
        }

        @Override
        public int hashCode() {
            return Objects.hash(accountId, invoiceDate);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            AccountWrapper other = (AccountWrapper) o;
            return accountId.equals(other.accountId) && invoiceDate.equals(other.invoiceDate);
        }
    }

Version with a nested map, no auxiliary objects are needed

        List<AccountInfo> result = List.of(
                        new AccountInfo("123", 80., 180., LocalDate.now()),
                        new AccountInfo("123", 120., 590., LocalDate.now()),
                        new AccountInfo("123", 30., 120., LocalDate.now().minusDays(3))
                )
                .stream()
                .collect(Collectors.groupingBy(
                        AccountInfo::getAccountId,
                        Collectors.toMap(
                                AccountInfo::getInvoiceDate,
                                UnaryOperator.identity(),
                                (acc1, acc2) -> new AccountInfo(
                                    acc1.getAccountId(),
                                    acc1.getVat() + acc2.getVat(),
                                    acc1.getTotalFee() + acc2.getTotalFee(),
                                    acc1.getInvoiceDate())
                        )))
                .values().stream()
                .flatMap(map -> map.values().stream())
                .collect(Collectors.toList());

        result.forEach(System.out::println);

output

AccountInfo{accountId='123', vat=200.0, totalFee=770.0, invoiceDate=2022-02-09}
AccountInfo{accountId='123', vat=30.0, totalFee=120.0, invoiceDate=2022-02-06}


问:
Assign incoming mail a category if subject has a match in one of multiple arrays of text
Goal: Code in ThisOutlookSession.

I am missing the condition for array 0 and the other arrays (1 to 4) are not in array form. See my code below.
Where Array 0 = #G126A, #G156A, #G186B, #GA265, #GH264A

IF the subject includes value in (array0)
    THEN Exit

ELSEIF the subject includes value in (array1)
    THEN assign category CAT1

ELSEIF the subject includes value in (array2)
    THEN assign category CAT2

ELSEIF the subject includes value in (array3)
    THEN assign category CAT3

ELSEIF the subject includes value in (array4)
    THEN assign category CAT4
```
<pre class="lang-vb prettyprint-override"><code>Option Explicit

Private WithEvents Items As Outlook.Items

Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
lbl_Exit:
Exit Sub
End Sub

Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
If TypeName(item) = "MailItem" Then
    AutoCategorize item
End If
lbl_Exit:
    Exit Sub
ErrorHandler:
    MsgBox Err.Number & " - " & Err.Description
    Err.Clear
    GoTo lbl_Exit
End Sub
</code>```

In a normal module enter the modified version of the code below, then restart Outlook (or manually run Application_Startup) to activate the event.

Public Sub AutoCategorize(olItem As MailItem)
With olItem
    If InStr(1, myitem.Subject, "100001") > 0 Or _
      InStr(1, myitem.Subject, "103401") > 0 Or _
      InStr(1, myitem.Subject, "108401") > 0 Or _
      InStr(1, myitem.Subject, "800899") > 0 Or _
      InStr(1, myitem.Subject, "800795") > 0 Or _
      InStr(1, myitem.Subject, "800755") > 0 Or _
      InStr(1, myitem.Subject, "800617") > 0 Or _
      InStr(1, myitem.Subject, "850519") > 0 Or _
      InStr(1, myitem.Subject, "212485") > 0 Then

        olItem.Categories = "CAT1"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "800880") > 0 Or _
      InStr(1, myitem.Subject, "221315") > 0 Or _
      InStr(1, myitem.Subject, "004083") > 0 Or _
      InStr(1, myitem.Subject, "218713") > 0 Or _
      InStr(1, myitem.Subject, "800824") > 0 Or _
      InStr(1, myitem.Subject, "004131") > 0 Or _
      InStr(1, myitem.Subject, "800404") > 0 Or _
      InStr(1, myitem.Subject, "020082") > 0 Or _
      InStr(1, myitem.Subject, "212445") > 0 Then
        olItem.Categories = "CAT2"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "215007") > 0 Or _
      InStr(1, myitem.Subject, "215989") > 0 Or _
      InStr(1, myitem.Subject, "005306") > 0 Or _
      InStr(1, myitem.Subject, "004025") > 0 Or _
      InStr(1, myitem.Subject, "060068") > 0 Or _
      InStr(1, myitem.Subject, "060193") > 0 Or _
      InStr(1, myitem.Subject, "030002") > 0 Or _
      InStr(1, myitem.Subject, "060103") > 0 Or _
      InStr(1, myitem.Subject, "217811") > 0 Then
        olItem.Categories = "CAT3"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "060001") > 0 Or _
      InStr(1, myitem.Subject, "215720") > 0 Or _
      InStr(1, myitem.Subject, "030001") > 0 Or _
      InStr(1, myitem.Subject, "030445") > 0 Or _
      InStr(1, myitem.Subject, "030388") > 0 Or _
      InStr(1, myitem.Subject, "030070") > 0 Or _
      InStr(1, myitem.Subject, "060065") > 0 Or _
      InStr(1, myitem.Subject, "601003") > 0 Or _
      InStr(1, myitem.Subject, "203093") > 0 Then
        olItem.Categories = "CAT4"
        olItem.Save
    End If
End With
lbl_Exit:
    Exit Sub
End Sub
```

答:
It will be tedious to generate arrays but it could be done this way.

Comment on previous answer post:

"some values are used multiple times between categories"

Private WithEvents Items As Items

Private Sub Application_Startup()
Set Items = Session.GetDefaultFolder(olFolderInbox).Items
End Sub

Private Sub Items_ItemAdd(ByVal item As Object)
If TypeOf item Is MailItem Then
    AutoCategorize item
End If
End Sub

Public Sub AutoCategorize(olItem As MailItem)

Dim array0 As Variant
Dim array1 As Variant
Dim array2 As Variant
Dim array3 As Variant
Dim array4 As Variant

Dim i As Long

array0 = Array("#G126A", "#G156A", "#G186B", "#GA265", "#GH264A")

For i = LBound(array0) To UBound(array0)
    If InStr(olItem.Subject, array0(i)) Then
        Exit Sub
    End If
Next

array1 = Array("100001", "103401", "108401")
For i = LBound(array1) To UBound(array1)
    If InStr(olItem.Subject, array1(i)) Then
        olItem.categories = "CAT1"
        Exit For
    End If
Next

array2 = Array("800880", "221315", "004083")
For i = LBound(array2) To UBound(array2)
    If InStr(olItem.Subject, array2(i)) Then
        olItem.categories = olItem.categories & "; " & "CAT2"
        Exit For
    End If
Next

array3 = Array("215007", "215989", "005306")
For i = LBound(array3) To UBound(array3)
    If InStr(olItem.Subject, array3(i)) Then
        olItem.categories = olItem.categories & "; " & "CAT3"
        Exit For
    End If
Next

array4 = Array("060001", "215720", "030001")
For i = LBound(array4) To UBound(array4)
    If InStr(olItem.Subject, array4(i)) Then
        olItem.categories = olItem.categories & "; " & "CAT4"
        Exit For
    End If
Next

olItem.Save

End Sub
```

Body:
Goal: Code in ThisOutlookSession.

I am missing the condition for array 0 and the other arrays (1 to 4) are not in array form. See my code below.
Where Array 0 = #G126A, #G156A, #G186B, #GA265, #GH264A

IF the subject includes value in (array0)
    THEN Exit

ELSEIF the subject includes value in (array1)
    THEN assign category CAT1

ELSEIF the subject includes value in (array2)
    THEN assign category CAT2

ELSEIF the subject includes value in (array3)
    THEN assign category CAT3

ELSEIF the subject includes value in (array4)
    THEN assign category CAT4

Option Explicit

Private WithEvents Items As Outlook.Items

Private Sub Application_Startup()
Dim olApp As Outlook.Application
Dim objNS As Outlook.NameSpace
Set olApp = Outlook.Application
Set objNS = olApp.GetNamespace("MAPI")
Set Items = objNS.GetDefaultFolder(olFolderInbox).Items
lbl_Exit:
Exit Sub
End Sub

Private Sub Items_ItemAdd(ByVal item As Object)
On Error GoTo ErrorHandler
If TypeName(item) = "MailItem" Then
    AutoCategorize item
End If
lbl_Exit:
    Exit Sub
ErrorHandler:
    MsgBox Err.Number & " - " & Err.Description
    Err.Clear
    GoTo lbl_Exit
End Sub

In a normal module enter the modified version of the code below, then restart Outlook (or manually run Application_Startup) to activate the event.

Public Sub AutoCategorize(olItem As MailItem)
With olItem
    If InStr(1, myitem.Subject, "100001") > 0 Or _
      InStr(1, myitem.Subject, "103401") > 0 Or _
      InStr(1, myitem.Subject, "108401") > 0 Or _
      InStr(1, myitem.Subject, "800899") > 0 Or _
      InStr(1, myitem.Subject, "800795") > 0 Or _
      InStr(1, myitem.Subject, "800755") > 0 Or _
      InStr(1, myitem.Subject, "800617") > 0 Or _
      InStr(1, myitem.Subject, "850519") > 0 Or _
      InStr(1, myitem.Subject, "212485") > 0 Then

        olItem.Categories = "CAT1"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "800880") > 0 Or _
      InStr(1, myitem.Subject, "221315") > 0 Or _
      InStr(1, myitem.Subject, "004083") > 0 Or _
      InStr(1, myitem.Subject, "218713") > 0 Or _
      InStr(1, myitem.Subject, "800824") > 0 Or _
      InStr(1, myitem.Subject, "004131") > 0 Or _
      InStr(1, myitem.Subject, "800404") > 0 Or _
      InStr(1, myitem.Subject, "020082") > 0 Or _
      InStr(1, myitem.Subject, "212445") > 0 Then
        olItem.Categories = "CAT2"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "215007") > 0 Or _
      InStr(1, myitem.Subject, "215989") > 0 Or _
      InStr(1, myitem.Subject, "005306") > 0 Or _
      InStr(1, myitem.Subject, "004025") > 0 Or _
      InStr(1, myitem.Subject, "060068") > 0 Or _
      InStr(1, myitem.Subject, "060193") > 0 Or _
      InStr(1, myitem.Subject, "030002") > 0 Or _
      InStr(1, myitem.Subject, "060103") > 0 Or _
      InStr(1, myitem.Subject, "217811") > 0 Then
        olItem.Categories = "CAT3"
        olItem.Save

    ElseIf InStr(1, myitem.Subject, "060001") > 0 Or _
      InStr(1, myitem.Subject, "215720") > 0 Or _
      InStr(1, myitem.Subject, "030001") > 0 Or _
      InStr(1, myitem.Subject, "030445") > 0 Or _
      InStr(1, myitem.Subject, "030388") > 0 Or _
      InStr(1, myitem.Subject, "030070") > 0 Or _
      InStr(1, myitem.Subject, "060065") > 0 Or _
      InStr(1, myitem.Subject, "601003") > 0 Or _
      InStr(1, myitem.Subject, "203093") > 0 Then
        olItem.Categories = "CAT4"
        olItem.Save
    End If
End With
lbl_Exit:
    Exit Sub
End Sub


问:
How to retrieve all-suggestion-accepted content of a Document on google Doc through API
As title, I manage to retrieve all-suggestion-accepted content on Google Docs through API. I have referred to its guideline and a couple of posts on this platform but in vain. Below is the snippet I currently have. Please Advise.</p>
```<code>function myFunction()
{
  var documentId ="My file ID";
  var doc = Docs.Documents.get(documentId);
  var  SUGGEST_MODE= "PREVIEW_SUGGESTIONS_ACCEPTED";
  var doc1 = Docs.Documents.get(documentId).setSuggestionsViewMode(SUGGEST_MODE);
  console.log(doc1.body.content)
}
</code>```

答:
Upon seeing the documentation, you should use it like this

Script:

```<code>function myFunction() {
  doc_id = '1s26M6g8PtSR65vRcsA90Vnn_gy1y3wj7glj8GxcNy_E';
  SUGGEST_MODE = 'PREVIEW_SUGGESTIONS_ACCEPTED'
  suggestions = Docs.Documents.get(doc_id, {
    'suggestionsViewMode': SUGGEST_MODE
  });

  new_content = '';

  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        new_content += element.textRun.content;
      });
  });

  console.log(new_content);
}

</code>```

Sample suggestions (with added paragraph):

Output:

EDIT:

Added an additional paragraph, and instead of just logging them, I have stored them in a single variable and printed at the end.

Reference:

documents.get

Body:
As title, I manage to retrieve all-suggestion-accepted content on Google Docs through API. I have referred to its guideline and a couple of posts on this platform but in vain. Below is the snippet I currently have. Please Advise.

function myFunction()
{
  var documentId ="My file ID";
  var doc = Docs.Documents.get(documentId);
  var  SUGGEST_MODE= "PREVIEW_SUGGESTIONS_ACCEPTED";
  var doc1 = Docs.Documents.get(documentId).setSuggestionsViewMode(SUGGEST_MODE);
  console.log(doc1.body.content)
}

Body:
Upon seeing the documentation, you should use it like this

Script:

function myFunction() {
  doc_id = '1s26M6g8PtSR65vRcsA90Vnn_gy1y3wj7glj8GxcNy_E';
  SUGGEST_MODE = 'PREVIEW_SUGGESTIONS_ACCEPTED'
  suggestions = Docs.Documents.get(doc_id, {
    'suggestionsViewMode': SUGGEST_MODE
  });

  new_content = '';

  suggestions.body.content.forEach(obj => {
    if(obj.paragraph)
      obj.paragraph.elements.forEach(element => {
        new_content += element.textRun.content;
      });
  });

  console.log(new_content);
}

Sample suggestions (with added paragraph):

Output:

EDIT:

Added an additional paragraph, and instead of just logging them, I have stored them in a single variable and printed at the end.

Reference:

documents.get


问:
Universal selector or body selector
I am kind of confused between universal selector and body selector now because I need to add

box-sizing:border-box;
Padding:0;
Margin:0;
```

Where should I keep this in universal selector or in body selector ?? Please clear my doubts.

答:
body selector will add those property to the  tag.

```<code>body{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}
</code>```

But universal selector * will apply those properties in each element of the html content. if the structure is like this.

```<code><body>
<h1></h1>
<p></p>
</body>
</code>```

when you apply

```<code>*{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}
</code>```

It'll be applied to each element. like this -

```<code>body, h1, p{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}
</code>```

Title: Universal selector or body selector

Body:
I am kind of confused between universal selector and body selector now because I need to add

box-sizing:border-box;
Padding:0;
Margin:0;

Where should I keep this in universal selector or in body selector ?? Please clear my doubts.

Body:
body selector will add those property to the <body> tag.

body{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}

But universal selector * will apply those properties in each element of the html content. if the structure is like this.

<body>
<h1></h1>
<p></p>
</body>

when you apply

*{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}

It'll be applied to each element. like this -

body, h1, p{
  box-sizing:border-box;
  Padding:0;
  Margin:0;
}


问:
How to set up file permissions for Laravel?
I'm using Apache Web Server that has the owner set to _www:_www. I never know what is the best practice with file permissions, for example when I create new Laravel 5 project.

Laravel 5 requires /storage folder to be writable. I found plenty of different approaches to make it work and I usually end with making it 777 chmod recursively. I know it's not the best idea though.

The official doc says:

Laravel may require some permissions to be configured: folders within
  storage and vendor require write access by the web server.

Does it mean that the web server needs access to the storage and vendor folders themselves too or just their current contents?

I assume that what is much better, is changing the owner instead of permissions. I changed all Laravel's files permissions recursively to _www:_www and that made the site work correctly, as if I changed chmod to 777. The problem is that now my text editor asks me for password each time I want to save any file and the same happens if I try to change anything in Finder, like for example copy a file.

What is the correct approach to solve these problems?

Change chmod

Change the owner of the files to match those of the
    web server and perhaps set the text editor (and Finder?) to skip
    asking for password, or make them use sudo

Change the owner of the web server to match the os user (I don't
know the consequences)

Something else

答:
I also follow the way to have user as owner, and user is member of www-data.

My sequence of command is a bit different:

```<code>cd /var/www/html/laravel-project-root
sudo chown -R $USER:www-data .

sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;

sudo find . -type d -exec chmod g+s {} \;  <----- NOTE THIS

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
</code>```

Please note the particularity of this very answer: I am the only (here) adding the group bit to every folder. In this way, if someone or something creates a new subfolder, it automatically has www-data as group

this happens when we are forced to deploy some userland files, preloaded using ftp, and so new subfolders folders are always owned from www-data group even if created by ftp client

Note also that the

sudo chgrp -R www-data storage bootstrap/cache >

is not needed if you do ALL of the commands in the list. But if you want to fix a ftp deploy, for example, and you didn't execute the 2nd line, so this is needed.

Body:
I also follow the way to have user as owner, and user is member of www-data.

My sequence of command is a bit different:

cd /var/www/html/laravel-project-root
sudo chown -R $USER:www-data .

sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;

sudo find . -type d -exec chmod g+s {} \;  <----- NOTE THIS

sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache

Please note the particularity of this very answer: I am the only (here) adding the group bit to every folder. In this way, if someone or something creates a new subfolder, it automatically has www-data as group

this happens when we are forced to deploy some userland files, preloaded using ftp, and so new subfolders folders are always owned from www-data group even if created by ftp client

Note also that the

sudo chgrp -R www-data storage bootstrap/cache >

is not needed if you do ALL of the commands in the list. But if you want to fix a ftp deploy, for example, and you didn't execute the 2nd line, so this is needed.


问:
How to use a C/C++ library (like NCurses) in Haxe
I have a cli written in Haxe and compiled to a binary via C++ (hxcpp). I would like to use ncurses in it. I have worked with ncurses in C and I've worked with JS externs in Haxe but I'm can't figure out the Haxe/C++ documentation to connection the two together.

I haven't used much more of the HXCPP compiler than the basic haxe command (ie not build files etc), à la:

```<code>haxe -lib somelib -cp src --cpp bin/cpp path.to.Main
</code>```

Basically, I can work with all custom code, but am struggling on externals. So I'm not entirely sure how many steps I am missing towards my goal.  But I can see a few major obstacles.

How to include ncurses in the build? ie. cc -lncurses -o out [etc...] in a Makefile.

How to include the proper externs to allow Haxe to compile at all without error. All the extern examples I see involve a class/namespace but NCurses functions don't have a class or namespace. I haven't found any documentation for a bare extern function.

Then of course the basics of including the headers properly (or the haxe compilation equivalent) in my actual Haxe code.

I know this is basically asking for a mini-tutorial, but I can't find examples or documentation that I can put together to accomplish this specific goal.

Thanks for any help you can lend.

答:
HXCPP uses an xml-based build system. When you launch haxe -cp src --cpp bin/cpp path.to.Main:

Haxe files are transpiled to C++ and a Build.xml is produced in the output directory, i.e. bin/cpp/Build.xml;

everything is then built by HXCPP, merging the newly generated project Build.xml with the global default xml definitions and then calling the compiler toolchain(s).

You can inject compiler flags, libraries to link, includes directories, etc., through the @:buildXml metadata, as described on the manual:

```<code>@:buildXml("
    <target id='haxe'>
       <lib name='-lncurses' if='linux'/>
       <lib name='ncurses.lib' if='windows'/>
    </target>
")
class Main{ ...
</code>```

These tags will be appended to the project Build.xml. The haxe target is the default target. Keep in mind that every toolchain (MSVC, gcc, Xcode, etc.) has its own syntax. You can see examples in the build.xml of cross-platform low-level projects like Systools or Lime.

You can add -D HXCPP_VERBOSE to the haxe command line to see which commands are actually launched: haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main.

As for externs, the simpler case is:

you write your C++ code, with #includes and everything needed, inside a @:cppFileCode() block; everything you write here is pasted as-is in the generated cpp file;

you mark one of your haxe functions, defined on one of the haxe classes, as @:native("nameOfTheCppFunction"), and the build system will join them together.

```<code>    @:cppFileCode("
        #include <ncurses.h>

        void nativeCppTest(){
             /* here goes your ncurses code */
             return;
        }
    ")

    class Main{
        public static function main()
        {
            myCppTest();
        }

        @:native("nativeCppTest")
        extern static function myCppTest():Void;
    }

</code>```

If you open the generated file (in this case bin/cpp/src/Main.cpp) you'll see that the haxe myCppTest() call is changed to its native version nativeCppTest().

If you would like to pass function arguments, and receive return values, you'll have to wrap those using the cpp.* standard library types. For example:

```<code>    @:cppFileCode("
        #include <ncurses.h>

        void nativeCppTest(const char* myString){
             /* here goes your ncurses code */
             return;
        }
    ")

    class Main{
        public static function main()
        {
            myCppTest("print this");
        }

        @:native("nativeCppTest")
        extern static function myCppTest(myString:cpp.ConstCharStar):Void;
    }

</code>```

Some of the conversions will be automatic (like, in this case, from a constant string to ConstCharStar), some will require an explicit cast; if you need to pass pointers to the C++ code, you can get it via cpp.RawConstPointer.addressOf(<haxe object>) (or RawPointer if not const):

```<code>    public static function main()
    {
        var myString:String = "print this";
        myCppTest(cast cpp.RawConstPointer.addressOf(myString));
    }
</code>```

Useful references:

C++ Magic by Hugh Sanderson

C++ extern example, everything in one file (MiniMP3 project)

Body:
I have a cli written in Haxe and compiled to a binary via C++ (hxcpp). I would like to use ncurses in it. I have worked with ncurses in C and I've worked with JS externs in Haxe but I'm can't figure out the Haxe/C++ documentation to connection the two together.

I haven't used much more of the HXCPP compiler than the basic haxe command (ie not build files etc), à la:

haxe -lib somelib -cp src --cpp bin/cpp path.to.Main

Basically, I can work with all custom code, but am struggling on externals. So I'm not entirely sure how many steps I am missing towards my goal.  But I can see a few major obstacles.

How to include ncurses in the build? ie. cc -lncurses -o out [etc...] in a Makefile.

How to include the proper externs to allow Haxe to compile at all without error. All the extern examples I see involve a class/namespace but NCurses functions don't have a class or namespace. I haven't found any documentation for a bare extern function.

Then of course the basics of including the headers properly (or the haxe compilation equivalent) in my actual Haxe code.

I know this is basically asking for a mini-tutorial, but I can't find examples or documentation that I can put together to accomplish this specific goal.

Thanks for any help you can lend.

Body:
HXCPP uses an xml-based build system. When you launch haxe -cp src --cpp bin/cpp path.to.Main:

Haxe files are transpiled to C++ and a Build.xml is produced in the output directory, i.e. bin/cpp/Build.xml;

everything is then built by HXCPP, merging the newly generated project Build.xml with the global default xml definitions and then calling the compiler toolchain(s).

You can inject compiler flags, libraries to link, includes directories, etc., through the @:buildXml metadata, as described on the manual:

@:buildXml("
    <target id='haxe'>
       <lib name='-lncurses' if='linux'/>
       <lib name='ncurses.lib' if='windows'/>
    </target>
")
class Main{ ...

These tags will be appended to the project Build.xml. The haxe target is the default target. Keep in mind that every toolchain (MSVC, gcc, Xcode, etc.) has its own syntax. You can see examples in the build.xml of cross-platform low-level projects like Systools or Lime.

You can add -D HXCPP_VERBOSE to the haxe command line to see which commands are actually launched: haxe -D HXCPP_VERBOSE -cp src --cpp bin/cpp path.to.Main.

As for externs, the simpler case is:

you write your C++ code, with #includes and everything needed, inside a @:cppFileCode() block; everything you write here is pasted as-is in the generated cpp file;

you mark one of your haxe functions, defined on one of the haxe classes, as @:native("nameOfTheCppFunction"), and the build system will join them together.

    @:cppFileCode("
        #include <ncurses.h>

        void nativeCppTest(){
             /* here goes your ncurses code */
             return;
        }
    ")

    class Main{
        public static function main()
        {
            myCppTest();
        }

        @:native("nativeCppTest")
        extern static function myCppTest():Void;
    }

If you open the generated file (in this case bin/cpp/src/Main.cpp) you'll see that the haxe myCppTest() call is changed to its native version nativeCppTest().

If you would like to pass function arguments, and receive return values, you'll have to wrap those using the cpp.* standard library types. For example:

    @:cppFileCode("
        #include <ncurses.h>

        void nativeCppTest(const char* myString){
             /* here goes your ncurses code */
             return;
        }
    ")

    class Main{
        public static function main()
        {
            myCppTest("print this");
        }

        @:native("nativeCppTest")
        extern static function myCppTest(myString:cpp.ConstCharStar):Void;
    }

Some of the conversions will be automatic (like, in this case, from a constant string to ConstCharStar), some will require an explicit cast; if you need to pass pointers to the C++ code, you can get it via cpp.RawConstPointer.addressOf(<haxe object>) (or RawPointer if not const):

    public static function main()
    {
        var myString:String = "print this";
        myCppTest(cast cpp.RawConstPointer.addressOf(myString));
    }

Useful references:

C++ Magic by Hugh Sanderson

C++ extern example, everything in one file (MiniMP3 project)


问:
ArgumentError, wrong number of arguments
I'm getting the error

```<code>ArgumentError in PagesController#home, wrong number of arguments (0 for 1)
</code>```

but I don't know why.  I have a Users model from Devise, and a Dplan model, where dplan belongs_to :user and a user has_many :dplans.  I'm trying to set up my site so that you can create a new dplan on the home page.  My home page view is this:

```<code><% if user_signed_in? %>
<h1>Hello <%= current_user.name %>! <h1>

<%= form_for @dplan do |f|%>
    <div class="field">
        <%= f.text_area :name %>
    </div>
    <div class="actions">
        <%= f.submit "Submit" %>
    </div>
<% end %>

<% else %>
<h1>DPlanner</h1>
<p>
    This is the home page for DPlanner.
</p>

<%= link_to "Sign up now!", new_user_registration_path, :class =>   "signup_button round" %>
<% end %>
</code>```

This is dplans_controller.rb:

```<code>class DplansController < ApplicationController

  def create
      @dplan = current_user.dplans.build(params[:dplan])
      if @dplan.save
          flash[:success]="Dplan created!"
          redirect_to root_path
      else
          render 'pages/home'
      end
  end

  def destroy
  end

end
</code>```

And here is pages_controller.rb:

```<code>class PagesController < ApplicationController

    def home
        @title = "Home"
        @dplan = Dplan.new if user_signed_in?
    end

end
</code>```

I don't understand why I'm getting this error message - the only argument needed on the page is dplan, which I define in the pages controller.  Help!

Here is dplan.rb:

```<code>class Dplan < ActiveRecord::Base
    attr_accessible :name

    belongs_to :user

    validates :name, :presence=>true, :length => { maximum => 30 }
    validates :user_id, :presence =>true

end
</code>```

答:
I had a similar issue when using Devise + Omniauth and symptoms included:

there was no application trace whatsoever

it wouldn't go away even if my controller method was empty.

other controllers worked just fine

it turned out to be some sort of name collision that went away when I renamed my method and controller. For example:

Invites#process Error (1 for 0)

Invitations#process --> Error (1 for 0)

Friends#Add --> No Error!

Hope this helps.

ContentLicense: CC BY-SA 3.0

Body:
I'm getting the error

ArgumentError in PagesController#home, wrong number of arguments (0 for 1)

but I don't know why.  I have a Users model from Devise, and a Dplan model, where dplan belongs_to :user and a user has_many :dplans.  I'm trying to set up my site so that you can create a new dplan on the home page.  My home page view is this:

<% if user_signed_in? %>

Hello <%= current_user.name %>!

<%= form_for @dplan do |f|%>

        <%= f.text_area :name %>

        <%= f.submit "Submit" %>

<% end %>

<% else %>

DPlanner

    This is the home page for DPlanner.

<%= link_to "Sign up now!", new_user_registration_path, :class =>   "signup_button round" %>
<% end %>

This is dplans_controller.rb:

class DplansController < ApplicationController

  def create
      @dplan = current_user.dplans.build(params[:dplan])
      if @dplan.save
          flash[:success]="Dplan created!"
          redirect_to root_path
      else
          render 'pages/home'
      end
  end

  def destroy
  end

end

And here is pages_controller.rb:

class PagesController < ApplicationController

    def home
        @title = "Home"
        @dplan = Dplan.new if user_signed_in?
    end

end

I don't understand why I'm getting this error message - the only argument needed on the page is dplan, which I define in the pages controller.  Help!

Here is dplan.rb:

class Dplan < ActiveRecord::Base
    attr_accessible :name

    belongs_to :user

    validates :name, :presence=>true, :length => { maximum => 30 }
    validates :user_id, :presence =>true

end


问:
Thymeleaf, how to make conditional statement with th:src?
If dish.imageFolder is not null - it should be

```<code><img th:src="@{${dish.imageFolder}}"/>
</code>```

If null - this image

```<code>  <img src="https://via.placeholder.com/150" alt=""/>
</code>```

答:
One option:

```<code><img th:src="${dish.imageFolder != null} ? @{${dish.imageFolder}} : 'https://via.placeholder.com/150'" />
</code>```

I would probably just use th:if though, like this:

```<code>  <img th:if="${dish.imageFolder != null}" th:src="@{${dish.imageFolder}}" />
  <img th:if="${dish.imageFolder == null}" src="https://via.placeholder.com/150" />
</code>```

Body:
If dish.imageFolder is not null - it should be

If null - this image

Body:
One option:

<img th:src="${dish.imageFolder != null} ? @{${dish.imageFolder}} : 'https://via.placeholder.com/150'" />

I would probably just use th:if though, like this:

  <img th:if="${dish.imageFolder != null}" th:src="@{${dish.imageFolder}}" />
  <img th:if="${dish.imageFolder == null}" src="https://via.placeholder.com/150" />


问:
Entity Framework edmx click on diagram very slow
Background first: I have a database-first EF6 model in Visual Studio 2015 (latest nuget 6.1.3 pointing to a local SQL Server 2014 SP1 Express database) on a Windows 10 Pro laptop. After I upgraded from Windows 8.1 and Visual Studio 2013. I also upgraded the model from EF5 about 6 months ago as well, but I don't think this is relevant, as I've also tried rebuilding from scratch.

The model: set of about 100 tables, 50 views and 250 associations.

The problem is every time I want to make changes to my model, any kind of click (left or right) on the .edmx diagram causes Visual Studio to become unresponsive for a few minutes. I've moved everything I can onto another diagram (views with no associations mostly) which does not have this problem, so I'm assuming the number of associations is the problem. Most of these are required foreign key associations pulled in from the database. It is however taking about half an hour to link up 3 FK associations for a view on my main diagram. I can understand if there is a limit on entities in a model, but I can't understand why simply clicking on the diagram should make Visual Studio become unresponsive. The task manager shows heavy CPU usage and no Disk use.

Clicking on any of the entities is fine, as is moving them around or editing them. The problem is clicking on the background canvas.

I have taken to updating the model from the database via the model browser, but I cannot get around using a right-click on the diagram to create new associations.

I've not seen any comments about this problem anywhere. Any suggestions of cause or workarounds?

BTW I have just reinstalled Windows 10 Pro and installed nothing but SQL Server 2014 SP1 Express and Visual Studio 2105 Pro. So there is nothing custom on my system.

UPDATE: ProcDump provides this stacktrace when DevEnv.exe becomes unresponsive, suggesting native code search for graphic objects:

```<code>[External Code]
[Managed to Native Transition]
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!<Module>.GeoSCursor.search(GeoSCursor* value)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.GetObjectsInRect(LRECT bbox, Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGLayoutObjectList items, VSGLayoutObject** ignoreItems, int numberItems, int numbertypes, int* types, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.GetObjectsInRect(LRECT bbox, Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGLayoutObjectList items, VSGLayoutObject** ignoreItems, int numberItems, int numbertypes, int* types, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.get_ObjectsInRectangle(double x0, double y0, double x1, double y1, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.HitTest(Microsoft.VisualStudio.Modeling.Diagrams.RectangleD hitArea, bool requireCompleteContainment, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.SpatialQuery(Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.SpatialDirection direction, Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement currentShape, Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement parentShape)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement.FindNextInChildShapes(Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement startFromChildShape, bool focusableRequired)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.ShapeAccessibleObject.GetChild(int index)
System.Windows.Forms.dll!System.Windows.Forms.AccessibleObject.GetFocused()
System.Windows.Forms.dll!System.Windows.Forms.AccessibleObject.Accessibility.IAccessible.accFocus.get()
System.Windows.Forms.dll!System.Windows.Forms.InternalAccessibleObject.System.Windows.Forms.UnsafeNativeMethods.IAccessibleInternal.get_accFocus()
</code>```

UPDATE2: XtraSimplicity has a solution which works for some, but not me. Thanks to his suggestions I have ruled this out as a direct graphics driver issue. I have an Intel HD Graphics Family and NVIdia GeForce GT 750M display adapters in my laptop. Intel is the usual active adapter, but the problem also appears when only NVidia is enabled. I've also tried the suggestion of disabling hardware support in Visual Studio, but if anything that just makes the performance of VS when an edmx is open even worse.

答:
If this helps anybody. Having same problem. When I try to generate model from db it takes roughly 18 minutes.
I am running EF 6.1.3. Sql Server 2014 management studio. VS 2015.
I ran this command and now it is super fast like a couple of seconds.
"ALTER DATABASE ROW  SET COMPATIBILITY_LEVEL = 110"
You need to restart the sql server service.</p>

Body:
Background first: I have a database-first EF6 model in Visual Studio 2015 (latest nuget 6.1.3 pointing to a local SQL Server 2014 SP1 Express database) on a Windows 10 Pro laptop. After I upgraded from Windows 8.1 and Visual Studio 2013. I also upgraded the model from EF5 about 6 months ago as well, but I don't think this is relevant, as I've also tried rebuilding from scratch.

The model: set of about 100 tables, 50 views and 250 associations.

The problem is every time I want to make changes to my model, any kind of click (left or right) on the .edmx diagram causes Visual Studio to become unresponsive for a few minutes. I've moved everything I can onto another diagram (views with no associations mostly) which does not have this problem, so I'm assuming the number of associations is the problem. Most of these are required foreign key associations pulled in from the database. It is however taking about half an hour to link up 3 FK associations for a view on my main diagram. I can understand if there is a limit on entities in a model, but I can't understand why simply clicking on the diagram should make Visual Studio become unresponsive. The task manager shows heavy CPU usage and no Disk use.

Clicking on any of the entities is fine, as is moving them around or editing them. The problem is clicking on the background canvas.

I have taken to updating the model from the database via the model browser, but I cannot get around using a right-click on the diagram to create new associations.

I've not seen any comments about this problem anywhere. Any suggestions of cause or workarounds?

BTW I have just reinstalled Windows 10 Pro and installed nothing but SQL Server 2014 SP1 Express and Visual Studio 2105 Pro. So there is nothing custom on my system.

UPDATE: ProcDump provides this stacktrace when DevEnv.exe becomes unresponsive, suggesting native code search for graphic objects:

[External Code]
[Managed to Native Transition]
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!<Module>.GeoSCursor.search(GeoSCursor* value)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.GetObjectsInRect(LRECT bbox, Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGLayoutObjectList items, VSGLayoutObject** ignoreItems, int numberItems, int numbertypes, int* types, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.GetObjectsInRect(LRECT bbox, Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGLayoutObjectList items, VSGLayoutObject** ignoreItems, int numberItems, int numbertypes, int* types, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.GraphObject.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphObject.VGGraph.get_ObjectsInRectangle(double x0, double y0, double x1, double y1, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.HitTest(Microsoft.VisualStudio.Modeling.Diagrams.RectangleD hitArea, bool requireCompleteContainment, bool searchSubGraphs)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.SpatialQuery(Microsoft.VisualStudio.Modeling.Diagrams.GraphWrapper.SpatialDirection direction, Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement currentShape, Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement parentShape)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement.FindNextInChildShapes(Microsoft.VisualStudio.Modeling.Diagrams.ShapeElement startFromChildShape, bool focusableRequired)
Microsoft.VisualStudio.Modeling.Sdk.Diagrams.14.0.dll!Microsoft.VisualStudio.Modeling.Diagrams.ShapeAccessibleObject.GetChild(int index)
System.Windows.Forms.dll!System.Windows.Forms.AccessibleObject.GetFocused()
System.Windows.Forms.dll!System.Windows.Forms.AccessibleObject.Accessibility.IAccessible.accFocus.get()
System.Windows.Forms.dll!System.Windows.Forms.InternalAccessibleObject.System.Windows.Forms.UnsafeNativeMethods.IAccessibleInternal.get_accFocus()

UPDATE2: XtraSimplicity has a solution which works for some, but not me. Thanks to his suggestions I have ruled this out as a direct graphics driver issue. I have an Intel HD Graphics Family and NVIdia GeForce GT 750M display adapters in my laptop. Intel is the usual active adapter, but the problem also appears when only NVidia is enabled. I've also tried the suggestion of disabling hardware support in Visual Studio, but if anything that just makes the performance of VS when an edmx is open even worse.


问:
xlsx error : Removed Records: Document Theme from /xl/workbook.xml part (Workbook)
I have a node app where I'm fetching an excel file from an s3 bucket, and converting the buffer to excel file using the exceljs node library. When I try to open the converted xlsx file, I get a pop-up asking to repair the file as follows :

When I click on Yes and open the file, I get the following error log

```<code><?xml version="1.0" encoding="UTF-8"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
   <logFileName>Repair Result to DownloadData.xml</logFileName>
   <summary>Errors were detected in file '/Users/Downloads/DownloadData.xlsx'</summary>
   <removedRecords summary="Following is a list of removed records:">
      <removedRecord>Removed Records: Document Theme from /xl/workbook.xml part (Workbook)</removedRecord>
   </removedRecords>
</recoveryLog>
</code>```

I'm not sure what exactly is causing this error. How do I prevent the repair pop-up?

答:
It helped me:

```<code>workbook.clearThemes();
</code>```

after load.

Body:
I have a node app where I'm fetching an excel file from an s3 bucket, and converting the buffer to excel file using the exceljs node library. When I try to open the converted xlsx file, I get a pop-up asking to repair the file as follows :

When I click on Yes and open the file, I get the following error log

<?xml version="1.0" encoding="UTF-8"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
   <logFileName>Repair Result to DownloadData.xml</logFileName>
   Errors were detected in file '/Users/Downloads/DownloadData.xlsx'
   <removedRecords summary="Following is a list of removed records:">
      <removedRecord>Removed Records: Document Theme from /xl/workbook.xml part (Workbook)</removedRecord>
   </removedRecords>
</recoveryLog>

I'm not sure what exactly is causing this error. How do I prevent the repair pop-up?

Body:
It helped me:

workbook.clearThemes();

after load.


问:
How does this function operate with partial application?
```<code>let all_contain_true l =
  not (List.mem false (List.map (List.mem true) l))
</code>```

How is partial application used to make this function work to see if all the lists in the giant list contain true

答:
The only partial application I see is List.mem true. When we evaluate this at the toplevel, we see:

# List.mem true;;
- : bool list -> bool = <fun>
```
<p>This expression returns a function which maps a <code>list</code> of <code>bool</code> values to a <code>bool</code> based on whether the list contains the value <code>true</code>.</p>
<p>We can see this is action:</p>
<pre class="lang-none prettyprint-override"><code># let f = List.mem true;;
val f : bool list -> bool = <fun>
# f [false; true; false];;
- : bool = true
# f [false; false];;
- : bool = false
</code>```

List.map takes a function and a list. List.mem true provides the function.

Style points

For what it's worth, the |> operator may be useful in streamlining this function, and we can give a name to that function.

```<code>let all_contain_true l =
  let contains_true = List.mem true in
  l |> List.map contains_true |> List.mem false |> not
</code>```

You could also locally open the List module.

```<code>let all_contain_true l =
  List.(
    let contains_true = mem true in
    l |> map contains_true |> mem false |> not
  )
</code>```

Body:
let all_contain_true l =
  not (List.mem false (List.map (List.mem true) l))

How is partial application used to make this function work to see if all the lists in the giant list contain true

Body:
The only partial application I see is List.mem true. When we evaluate this at the toplevel, we see:

# List.mem true;;
- : bool list -> bool = <fun>

This expression returns a function which maps a list of bool values to a bool based on whether the list contains the value true.

We can see this is action:

# let f = List.mem true;;
val f : bool list -> bool = <fun>
# f [false; true; false];;
- : bool = true
# f [false; false];;
- : bool = false

List.map takes a function and a list. List.mem true provides the function.

Style points

For what it's worth, the |> operator may be useful in streamlining this function, and we can give a name to that function.

let all_contain_true l =
  let contains_true = List.mem true in
  l |> List.map contains_true |> List.mem false |> not

You could also locally open the List module.

let all_contain_true l =
  List.(
    let contains_true = mem true in
    l |> map contains_true |> mem false |> not
  )


问:
ModuleNotFoundError on own folder
I have this folder structure:

```<code>main.py
utils
--forms.py
</code>```

and am now trying in main.py to import something from forms.py with this:

from utils.forms import search_form

but I am getting this Exception

```<code>Traceback (most recent call last):
  File "/home/kofi/Desktop/projects/groundtruth_auswertung/main.py", line 4, in <module>
    from utils.forms import search_form
ModuleNotFoundError: No module named 'utils.forms'; 'utils' is not a package
</code>```

答:
Create a file named __init__.py in the utils folder, which allows the folder to be used as a package. (The file doesn't have to have anything inside)

This is only necessary on python 2 though, in python 3 it works automatically without the need for such file.

Title: ModuleNotFoundError on own folder

Body:
I have this folder structure:

main.py
utils
--forms.py

and am now trying in main.py to import something from forms.py with this:

from utils.forms import search_form

but I am getting this Exception

Traceback (most recent call last):
  File "/home/kofi/Desktop/projects/groundtruth_auswertung/main.py", line 4, in <module>
    from utils.forms import search_form
ModuleNotFoundError: No module named 'utils.forms'; 'utils' is not a package


问:
Remove NAs from variables feeding into tbl_uvregression and geepack::geeglm without keeping only complete records
I'm using gtsummary::tbl_uvregression to construct a univariate regression table modeled with geepack::geeglm.

Some variables contain NA values that are breaking the GEE models in the table.

x There was an error constructing model geepack::geeglm(formula = tts_participant ~ omb_race, data = ., family = poisson, id = School Name, corstr = "independence", scale.fix = TRUE) See error below.
Error in mutate_cols():
! Problem with mutate() column model.
i model = map(...).
x Error in geese.fit(xx, yy, id, offset, soffset, w, waves = waves, zsca, : nrow(zsca) and length(y) not match
Caused by error:
! Error in geese.fit(xx, yy, id, offset, soffset, w, waves = waves, zsca, : nrow(zsca) and length(y) not match

You would generally set data = na.omit(data) for geepack::geeglm. However, I only want to remove NAs for the variables that I'm looking at in the table. na.action = na.omit does not work. I would like to avoid computing a gtsummary::tbl_uvregression table for each individual variable.

How do I instruct tbl_uvregression to remove the NAs only for the specific model being generated. Here is my attempt:

```<code>tbl_uvregression(
method = geepack::geeglm,
y = tts_participant,
include = -`School Name`,
method.args = list(
  family = poisson,
  data = na.omit(data),
  #na.action = na.omit,
  id = `School Name`,
  corstr = "independence",
  scale.fix = TRUE
),
exponentiate = TRUE,
add_estimate_to_reference_rows = FALSE
</code>```

)

Thank you!

答:
The geepack::geeglm() is funny how it doesn't handle the NA values for us. When I've come across this, I write a small wrapper function for geeglm() that deletes the missing values before passing to geeglm(). Example below! Happy Programming!

library(gtsummary)
library(tidyverse)
packageVersion("gtsummary")
#> [1] '1.5.2'

my_geeglm <- function(formula, data, id, ...) {
  # capture id input (since it's unquoted)
  id <- rlang::enexpr(id)

  # keep compelte cases amoung the variables needed in the model
  data <-
    select(data, all_of(all.vars(formula)), !!id) %>%
    dplyr::filter(complete.cases(.))

  # build GEE model
  rlang::inject(
    geepack::geeglm(
      formula = formula,
      data = data,
      id = !!id, # inserting unquoted id column name
      ...
    )
  )
}

data(dietox, package = "geepack")

dietox %>%
  select(Pig, Weight, Cu, Feed) %>%
  tbl_uvregression(
    y = Weight,
    method = my_geeglm,
    method.args = list(id = Pig, family = poisson("identity"), corstr = "ar1"),
    include = -Pig
  ) %>%
  as_kable() # convert to kable to show in SO
```

Characteristic
N
Beta
95% CI
p-value

Cu
861

Cu000

—
—

Cu035

-0.49
-3.5, 2.5
0.7

Cu175

1.8
-1.9, 5.5
0.3

Feed
789
0.43
0.42, 0.45
<0.001

Created on 2022-02-09 by the reprex package (v2.0.1)

Body:
I'm using gtsummary::tbl_uvregression to construct a univariate regression table modeled with geepack::geeglm.

Some variables contain NA values that are breaking the GEE models in the table.

x There was an error constructing model geepack::geeglm(formula = tts_participant ~ omb_race, data = ., family = poisson, id = School Name, corstr = "independence", scale.fix = TRUE) See error below.
Error in mutate_cols():
! Problem with mutate() column model.
i model = map(...).
x Error in geese.fit(xx, yy, id, offset, soffset, w, waves = waves, zsca, : nrow(zsca) and length(y) not match
Caused by error:
! Error in geese.fit(xx, yy, id, offset, soffset, w, waves = waves, zsca, : nrow(zsca) and length(y) not match

You would generally set data = na.omit(data) for geepack::geeglm. However, I only want to remove NAs for the variables that I'm looking at in the table. na.action = na.omit does not work. I would like to avoid computing a gtsummary::tbl_uvregression table for each individual variable.

How do I instruct tbl_uvregression to remove the NAs only for the specific model being generated. Here is my attempt:

tbl_uvregression(
method = geepack::geeglm,
y = tts_participant,
include = -`School Name`,
method.args = list(
  family = poisson,
  data = na.omit(data),
  #na.action = na.omit,
  id = `School Name`,
  corstr = "independence",
  scale.fix = TRUE
),
exponentiate = TRUE,
add_estimate_to_reference_rows = FALSE

)

Thank you!

Body:
The geepack::geeglm() is funny how it doesn't handle the NA values for us. When I've come across this, I write a small wrapper function for geeglm() that deletes the missing values before passing to geeglm(). Example below! Happy Programming!

library(gtsummary)
library(tidyverse)
packageVersion("gtsummary")
#> [1] '1.5.2'

my_geeglm <- function(formula, data, id, ...) {
  # capture id input (since it's unquoted)
  id <- rlang::enexpr(id)

  # keep compelte cases amoung the variables needed in the model
  data <-
    select(data, all_of(all.vars(formula)), !!id) %>%
    dplyr::filter(complete.cases(.))

  # build GEE model
  rlang::inject(
    geepack::geeglm(
      formula = formula,
      data = data,
      id = !!id, # inserting unquoted id column name
      ...
    )
  )
}

data(dietox, package = "geepack")

dietox %>%
  select(Pig, Weight, Cu, Feed) %>%
  tbl_uvregression(
    y = Weight,
    method = my_geeglm,
    method.args = list(id = Pig, family = poisson("identity"), corstr = "ar1"),
    include = -Pig
  ) %>%
  as_kable() # convert to kable to show in SO

Characteristic
N
Beta
95% CI
p-value

Cu
861

Cu000

—
—

Cu035

-0.49
-3.5, 2.5
0.7

Cu175

1.8
-1.9, 5.5
0.3

Feed
789
0.43
0.42, 0.45
<0.001

Created on 2022-02-09 by the reprex package (v2.0.1)