问:
Reading from flash that's not part of the application
I'm programming bare-metal embedded, so no OS etc. on a STM32L4 (ARM Cortex M4). I have a separate page in flash, which is written by a bootloader (it is not and should not be part of my application binary, this is a must). In this page, I store configuration parameters that will be used in my application. This configuration page may change, but not during runtime, after a change I reset the processor.

How can I access this data in flash most nicely?

My definition of nice is (in this order of priority):
- support for (u)int32_t, (u)int8_t, bool, char[fixed-size]
- little overhead when compared to #define PARAM (1) or constexpr
- typesafe usage (i.e. uint8_t var = CONFIG_CHAR_ARRAY shall issue atleast a warning)
- no RAM copy
- readability of the configuration parameters while debugging (using STM32CubeIDE)

The solution shall scale for all possible 2048 bytes of the flashpage. Code generation is anyhow part of the process.

So far, I have tested two variants (I am coming from plain C but am using (potentially modern) C++ in this project). My current testcase is

```<code>    if (param) function_call();
</code>```

but it should also work for other cases such as

```<code>    for(int i = 0; i < param2; i++)
</code>```

define with pointer cast

```<code>#define CONF_PARAM1 (*(bool*)(CONFIG_ADDRESS + 0x0083))
</code>```

Which leads to (using -Os):

```<code>8008872:    4b1b        ldr r3, [pc, #108]  ; (80088e0 <_Z16main_applicationv+0xac>)
8008874:    781b        ldrb    r3, [r3, #0]
8008876:    b10b        cbz r3, 800887c <_Z16main_applicationv+0x48>
8008878:    f7ff ff56   bl  8008728 <_Z10function_callv>

80088e0:    0801f883    .word   0x0801f883
</code>```

const variable

```<code>const bool CONF_PARAM1 = *(bool*)(CONFIG_ADDRESS + 0x0083);
</code>```

leading to

```<code>800887c:    4b19        ldr r3, [pc, #100]  ; (80088e4 <_Z16main_applicationv+0xb0>)
800887e:    781b        ldrb    r3, [r3, #0]
8008880:    b10b        cbz r3, 8008886 <_Z16main_applicationv+0x52>
8008882:    f000 f899   bl  8008728 <_Z10function_callv>

80088e4:    200000c0    .word   0x200000c0
</code>```

I dislike option 2, as it adds a RAM copy (would not scale well for 2048 bytes of config), option 1 looks like very old c style and does not help while debugging. I struggle to find another option using the linker script, as I do not find a way to not end up with the variable being in the application's binary.

Is there any better way of doing this?

答:
You can isolate the variables in question their own section.  There is more than one way to do that.  The tools build normally and do all the addressing work.  Like using structs across compile domains you need to be extremely careful and probably put checks into the code, but you can build the binary and only load it or all but the other flash contents, then at that time or later you can change the VALUES of the variables in the other section and build and isolate those into their own load.

Testing the theory

vectors.s

```<code>.globl _start
_start:
.word 0x20001000
.word reset

.thumb_func
reset:
    bl main
    b .

.globl dummy
.thumb_func
dummy:
    bx lr
</code>```

so.c

```<code>extern volatile unsigned int x;
extern volatile unsigned short y;
extern volatile unsigned char z[7];
extern void dummy ( unsigned int );
int main ( void )
{
    dummy(x);
    dummy(y);
    dummy(z[0]<<z[1]);
    return(0);
}
</code>```

flashvars.c

```<code>volatile unsigned int x=1;
volatile unsigned short y=3;
volatile unsigned char z[7]={1,2,3,4,5,6,7};
</code>```

flash.ld

```<code>MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o } > rom1
}
</code>```

build

```<code>arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 vectors.s -o vectors.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld vectors.o so.o flashvars.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy -R .vars -O binary so.elf so.bin
</code>```

examine

```<code>Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <dummy>:
 800000e:   4770        bx  lr

08000010 <main>:
 8000010:   4b08        ldr r3, [pc, #32]   ; (8000034 <main+0x24>)
 8000012:   b510        push    {r4, lr}
 8000014:   6818        ldr r0, [r3, #0]
 8000016:   f7ff fffa   bl  800000e <dummy>
 800001a:   4b07        ldr r3, [pc, #28]   ; (8000038 <main+0x28>)
 800001c:   8818        ldrh    r0, [r3, #0]
 800001e:   b280        uxth    r0, r0
 8000020:   f7ff fff5   bl  800000e <dummy>
 8000024:   4b05        ldr r3, [pc, #20]   ; (800003c <main+0x2c>)
 8000026:   7818        ldrb    r0, [r3, #0]
 8000028:   785b        ldrb    r3, [r3, #1]
 800002a:   4098        lsls    r0, r3
 800002c:   f7ff ffef   bl  800000e <dummy>
 8000030:   2000        movs    r0, #0
 8000032:   bd10        pop {r4, pc}
 8000034:   0800200c    stmdaeq r0, {r2, r3, sp}
 8000038:   08002008    stmdaeq r0, {r3, sp}
 800003c:   08002000    stmdaeq r0, {sp}

Disassembly of section .vars:

08002000 <z>:
 8002000:   04030201    streq   r0, [r3], #-513 ; 0xfffffdff
 8002004:   00070605    andeq   r0, r7, r5, lsl #12

08002008 <y>:
 8002008:   00000003    andeq   r0, r0, r3

0800200c <x>:
 800200c:   00000001    andeq   r0, r0, r1
</code>```

that looks good

```<code>hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 02 f8 fe e7 70 47  |... ..........pG|
00000010  08 4b 10 b5 18 68 ff f7  fa ff 07 4b 18 88 80 b2  |.K...h.....K....|
00000020  ff f7 f5 ff 05 4b 18 78  5b 78 98 40 ff f7 ef ff  |.....K.x[x.@....|
00000030  00 20 10 bd 0c 20 00 08  08 20 00 08 00 20 00 08  |. ... ... ... ..|
00000040
</code>```

as does that.

```<code>arm-none-eabi-objcopy -j .vars -O binary so.elf sovars.bin

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010  47 43 43 3a 20 28 47 4e  55 29 20 39 2e 33 2e 30  |GCC: (GNU) 9.3.0|
00000020  00 41 30 00 00 00 61 65  61 62 69 00 01 26 00 00  |.A0...aeabi..&..|
00000030  00 05 43 6f 72 74 65 78  2d 4d 30 00 06 0c 07 4d  |..Cortex-M0....M|
00000040  09 01 12 04 14 01 15 01  17 03 18 01 19 01 1a 01  |................|
00000050  1e 02                                             |..|
00000052
</code>```

hah, okay a little more work.

```<code>MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o(.data) } > rom1
}

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010
</code>```

much better.

I strongly recommend against structs across compile domains and this falls into that category as the build for the real data is separate and between the code build and the data build you could get data that doesn't land the same, when I do things like this I put in protections to catch the problem during execution before it goes off the rails (or better at build time).  It is not a case of if it is a case of when.  Implementation defined means implementation defined.

But thinking about your question this became an easy solution.  And yes technically this data is read only, const this or that, but 1) does volatile and const go together?  and 2) do you really want/need to do that?

Does it even need to be volatile?  Probably not, just banged that out to start with. Switching it to const the tool puts them in .rodata.  Well my tool does depends on how you write your linker script and I think the version of binutils.

so.c

```<code>extern const unsigned int x;
extern const unsigned short y;
extern const unsigned char z[7];
extern void dummy ( unsigned int );
int main ( void )
{
    dummy(x);
    dummy(y);
    dummy(z[0]<<z[1]);
    return(0);
}
</code>```

flashvars.c

```<code>const unsigned int x=1;
const unsigned short y=3;
const unsigned char z[7]={1,2,3,4,5,6,7};
</code>```

flash.ld

```<code>MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o(.rodata) } > rom1
}
</code>```

output

```<code>Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <dummy>:
 800000e:   4770        bx  lr

08000010 <main>:
 8000010:   4b08        ldr r3, [pc, #32]   ; (8000034 <main+0x24>)
 8000012:   b510        push    {r4, lr}
 8000014:   6818        ldr r0, [r3, #0]
 8000016:   f7ff fffa   bl  800000e <dummy>
 800001a:   4b07        ldr r3, [pc, #28]   ; (8000038 <main+0x28>)
 800001c:   8818        ldrh    r0, [r3, #0]
 800001e:   f7ff fff6   bl  800000e <dummy>
 8000022:   4b06        ldr r3, [pc, #24]   ; (800003c <main+0x2c>)
 8000024:   7818        ldrb    r0, [r3, #0]
 8000026:   785b        ldrb    r3, [r3, #1]
 8000028:   4098        lsls    r0, r3
 800002a:   f7ff fff0   bl  800000e <dummy>
 800002e:   2000        movs    r0, #0
 8000030:   bd10        pop {r4, pc}
 8000032:   46c0        nop         ; (mov r8, r8)
 8000034:   0800200c    stmdaeq r0, {r2, r3, sp}
 8000038:   08002008    stmdaeq r0, {r3, sp}
 800003c:   08002000    stmdaeq r0, {sp}

Disassembly of section .vars:

08002000 <z>:
 8002000:   04030201    streq   r0, [r3], #-513 ; 0xfffffdff
 8002004:   00070605    andeq   r0, r7, r5, lsl #12

08002008 <y>:
 8002008:   00000003    andeq   r0, r0, r3

0800200c <x>:
 800200c:   00000001    andeq   r0, r0, r1

hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 02 f8 fe e7 70 47  |... ..........pG|
00000010  08 4b 10 b5 18 68 ff f7  fa ff 07 4b 18 88 ff f7  |.K...h.....K....|
00000020  f6 ff 06 4b 18 78 5b 78  98 40 ff f7 f0 ff 00 20  |...K.x[x.@..... |
00000030  10 bd c0 46 0c 20 00 08  08 20 00 08 00 20 00 08  |...F. ... ... ..|
00000040

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010
</code>```

Body:
I'm programming bare-metal embedded, so no OS etc. on a STM32L4 (ARM Cortex M4). I have a separate page in flash, which is written by a bootloader (it is not and should not be part of my application binary, this is a must). In this page, I store configuration parameters that will be used in my application. This configuration page may change, but not during runtime, after a change I reset the processor.

How can I access this data in flash most nicely?

My definition of nice is (in this order of priority):
- support for (u)int32_t, (u)int8_t, bool, char[fixed-size]
- little overhead when compared to #define PARAM (1) or constexpr
- typesafe usage (i.e. uint8_t var = CONFIG_CHAR_ARRAY shall issue atleast a warning)
- no RAM copy
- readability of the configuration parameters while debugging (using STM32CubeIDE)

The solution shall scale for all possible 2048 bytes of the flashpage. Code generation is anyhow part of the process.

So far, I have tested two variants (I am coming from plain C but am using (potentially modern) C++ in this project). My current testcase is

    if (param) function_call();

but it should also work for other cases such as

    for(int i = 0; i < param2; i++)

define with pointer cast

#define CONF_PARAM1 (*(bool*)(CONFIG_ADDRESS + 0x0083))

Which leads to (using -Os):

8008872:    4b1b        ldr r3, [pc, #108]  ; (80088e0 <_Z16main_applicationv+0xac>)
8008874:    781b        ldrb    r3, [r3, #0]
8008876:    b10b        cbz r3, 800887c <_Z16main_applicationv+0x48>
8008878:    f7ff ff56   bl  8008728 <_Z10function_callv>

80088e0:    0801f883    .word   0x0801f883

const variable

const bool CONF_PARAM1 = *(bool*)(CONFIG_ADDRESS + 0x0083);

leading to

800887c:    4b19        ldr r3, [pc, #100]  ; (80088e4 <_Z16main_applicationv+0xb0>)
800887e:    781b        ldrb    r3, [r3, #0]
8008880:    b10b        cbz r3, 8008886 <_Z16main_applicationv+0x52>
8008882:    f000 f899   bl  8008728 <_Z10function_callv>

80088e4:    200000c0    .word   0x200000c0

I dislike option 2, as it adds a RAM copy (would not scale well for 2048 bytes of config), option 1 looks like very old c style and does not help while debugging. I struggle to find another option using the linker script, as I do not find a way to not end up with the variable being in the application's binary.

Is there any better way of doing this?

Body:
You can isolate the variables in question their own section.  There is more than one way to do that.  The tools build normally and do all the addressing work.  Like using structs across compile domains you need to be extremely careful and probably put checks into the code, but you can build the binary and only load it or all but the other flash contents, then at that time or later you can change the VALUES of the variables in the other section and build and isolate those into their own load.

Testing the theory

vectors.s

.globl _start
_start:
.word 0x20001000
.word reset

.thumb_func
reset:
    bl main
    b .

.globl dummy
.thumb_func
dummy:
    bx lr

so.c

extern volatile unsigned int x;
extern volatile unsigned short y;
extern volatile unsigned char z[7];
extern void dummy ( unsigned int );
int main ( void )
{
    dummy(x);
    dummy(y);
    dummy(z[0]<<z[1]);
    return(0);
}

flashvars.c

volatile unsigned int x=1;
volatile unsigned short y=3;
volatile unsigned char z[7]={1,2,3,4,5,6,7};

flash.ld

MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o } > rom1
}

build

arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 vectors.s -o vectors.o
arm-none-eabi-ld -nostdlib -nostartfiles -T flash.ld vectors.o so.o flashvars.o -o so.elf
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy -R .vars -O binary so.elf so.bin

examine

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <dummy>:
 800000e:   4770        bx  lr

08000010 <main>:
 8000010:   4b08        ldr r3, [pc, #32]   ; (8000034 <main+0x24>)
 8000012:   b510        push    {r4, lr}
 8000014:   6818        ldr r0, [r3, #0]
 8000016:   f7ff fffa   bl  800000e <dummy>
 800001a:   4b07        ldr r3, [pc, #28]   ; (8000038 <main+0x28>)
 800001c:   8818        ldrh    r0, [r3, #0]
 800001e:   b280        uxth    r0, r0
 8000020:   f7ff fff5   bl  800000e <dummy>
 8000024:   4b05        ldr r3, [pc, #20]   ; (800003c <main+0x2c>)
 8000026:   7818        ldrb    r0, [r3, #0]
 8000028:   785b        ldrb    r3, [r3, #1]
 800002a:   4098        lsls    r0, r3
 800002c:   f7ff ffef   bl  800000e <dummy>
 8000030:   2000        movs    r0, #0
 8000032:   bd10        pop {r4, pc}
 8000034:   0800200c    stmdaeq r0, {r2, r3, sp}
 8000038:   08002008    stmdaeq r0, {r3, sp}
 800003c:   08002000    stmdaeq r0, {sp}

Disassembly of section .vars:

08002000 <z>:
 8002000:   04030201    streq   r0, [r3], #-513 ; 0xfffffdff
 8002004:   00070605    andeq   r0, r7, r5, lsl #12

08002008 <y>:
 8002008:   00000003    andeq   r0, r0, r3

0800200c <x>:
 800200c:   00000001    andeq   r0, r0, r1

that looks good

hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 02 f8 fe e7 70 47  |... ..........pG|
00000010  08 4b 10 b5 18 68 ff f7  fa ff 07 4b 18 88 80 b2  |.K...h.....K....|
00000020  ff f7 f5 ff 05 4b 18 78  5b 78 98 40 ff f7 ef ff  |.....K.x[x.@....|
00000030  00 20 10 bd 0c 20 00 08  08 20 00 08 00 20 00 08  |. ... ... ... ..|
00000040

as does that.

arm-none-eabi-objcopy -j .vars -O binary so.elf sovars.bin

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010  47 43 43 3a 20 28 47 4e  55 29 20 39 2e 33 2e 30  |GCC: (GNU) 9.3.0|
00000020  00 41 30 00 00 00 61 65  61 62 69 00 01 26 00 00  |.A0...aeabi..&..|
00000030  00 05 43 6f 72 74 65 78  2d 4d 30 00 06 0c 07 4d  |..Cortex-M0....M|
00000040  09 01 12 04 14 01 15 01  17 03 18 01 19 01 1a 01  |................|
00000050  1e 02                                             |..|
00000052

hah, okay a little more work.

MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o(.data) } > rom1
}

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010

much better.

I strongly recommend against structs across compile domains and this falls into that category as the build for the real data is separate and between the code build and the data build you could get data that doesn't land the same, when I do things like this I put in protections to catch the problem during execution before it goes off the rails (or better at build time).  It is not a case of if it is a case of when.  Implementation defined means implementation defined.

But thinking about your question this became an easy solution.  And yes technically this data is read only, const this or that, but 1) does volatile and const go together?  and 2) do you really want/need to do that?

Does it even need to be volatile?  Probably not, just banged that out to start with. Switching it to const the tool puts them in .rodata.  Well my tool does depends on how you write your linker script and I think the version of binutils.

so.c

extern const unsigned int x;
extern const unsigned short y;
extern const unsigned char z[7];
extern void dummy ( unsigned int );
int main ( void )
{
    dummy(x);
    dummy(y);
    dummy(z[0]<<z[1]);
    return(0);
}

flashvars.c

const unsigned int x=1;
const unsigned short y=3;
const unsigned char z[7]={1,2,3,4,5,6,7};

flash.ld

MEMORY
{
    rom0 : ORIGIN = 0x08000000, LENGTH = 0x1000
    rom1 : ORIGIN = 0x08002000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom0
    .vars : { flashvars.o(.rodata) } > rom1
}

output

Disassembly of section .text:

08000000 <_start>:
 8000000:   20001000    andcs   r1, r0, r0
 8000004:   08000009    stmdaeq r0, {r0, r3}

08000008 <reset>:
 8000008:   f000 f802   bl  8000010 <main>
 800000c:   e7fe        b.n 800000c <reset+0x4>

0800000e <dummy>:
 800000e:   4770        bx  lr

08000010 <main>:
 8000010:   4b08        ldr r3, [pc, #32]   ; (8000034 <main+0x24>)
 8000012:   b510        push    {r4, lr}
 8000014:   6818        ldr r0, [r3, #0]
 8000016:   f7ff fffa   bl  800000e <dummy>
 800001a:   4b07        ldr r3, [pc, #28]   ; (8000038 <main+0x28>)
 800001c:   8818        ldrh    r0, [r3, #0]
 800001e:   f7ff fff6   bl  800000e <dummy>
 8000022:   4b06        ldr r3, [pc, #24]   ; (800003c <main+0x2c>)
 8000024:   7818        ldrb    r0, [r3, #0]
 8000026:   785b        ldrb    r3, [r3, #1]
 8000028:   4098        lsls    r0, r3
 800002a:   f7ff fff0   bl  800000e <dummy>
 800002e:   2000        movs    r0, #0
 8000030:   bd10        pop {r4, pc}
 8000032:   46c0        nop         ; (mov r8, r8)
 8000034:   0800200c    stmdaeq r0, {r2, r3, sp}
 8000038:   08002008    stmdaeq r0, {r3, sp}
 800003c:   08002000    stmdaeq r0, {sp}

Disassembly of section .vars:

08002000 <z>:
 8002000:   04030201    streq   r0, [r3], #-513 ; 0xfffffdff
 8002004:   00070605    andeq   r0, r7, r5, lsl #12

08002008 <y>:
 8002008:   00000003    andeq   r0, r0, r3

0800200c <x>:
 800200c:   00000001    andeq   r0, r0, r1

hexdump -C so.bin
00000000  00 10 00 20 09 00 00 08  00 f0 02 f8 fe e7 70 47  |... ..........pG|
00000010  08 4b 10 b5 18 68 ff f7  fa ff 07 4b 18 88 ff f7  |.K...h.....K....|
00000020  f6 ff 06 4b 18 78 5b 78  98 40 ff f7 f0 ff 00 20  |...K.x[x.@..... |
00000030  10 bd c0 46 0c 20 00 08  08 20 00 08 00 20 00 08  |...F. ... ... ..|
00000040

hexdump -C sovars.bin
00000000  01 02 03 04 05 06 07 00  03 00 00 00 01 00 00 00  |................|
00000010


来源: stackexchange

问:
Saving Files c# - without overwriting?
I am saving data to a file every 60 secs, I have it saving every 60 secs ok but it deletes the previous data added. Is there a way in which it would add to the file rather than overwrite it. And without using save dialog as it is done in the background.

Any feedback is greatly appreciated

答:
It seems opening the File in Append mode will solve your problem.
http://msdn.microsoft.com/en-us/library/3zc0w663.aspx</p>

ContentLicense: CC BY-SA 3.0

Title: Saving Files c# - without overwriting?


问:
Highcharts dynamically change bar color based on value
I am creating a column type graph using json data. Here is the JS function i call to get the data using ajax call and plot the chart.

```<code>function getChart(){
    var categorySeries = [];
    var dataSeries = [];
    var url = "CallToControllerURL";

    $.getJSON(url, function(response) {
        $.each(response, function(i, item) {
            categorySeries .push(response[i].dateVal);
            dataSeries.push(response[i].count);
        });

        $('#chartDiv').highcharts({
            chart : {type : 'column'},
            title : {text : 'Date vs Count'},
            xAxis : {categories : categorySeries, crosshair : true},
            yAxis : {allowDecimals: false, min : 0, title : { text : 'Count'}},
            plotOptions : { column : {  pointPadding : 0.2, borderWidth : 0,    allowPointSelect: true  } },
            series : [ {name : 'Nbr of Records',data : dataSeries } ]
        });
    });
}
</code>```

I want to be able to modify the color of bar for any day if the count is greater than a particular value, say 10.

This is how the json input to the function.

```<code>[{"id":3,"dateVal":"2015-11-12","count":6},{"id":2,"dateVal":"2015-11-11","count":8},{"id":1,"dateVal":"2015-11-10","count":5}]
</code>```

Any suggestions how i can do this?

答:
```<code>plotOptions: {
                column: {
                    zones: [
                        {
                            value: -1,
                            color: 'red',
                        },
                        {
                            color: 'green'//default color
                        },
                    ],
                },
            }
</code>```

Body:
I am creating a column type graph using json data. Here is the JS function i call to get the data using ajax call and plot the chart.

function getChart(){
    var categorySeries = [];
    var dataSeries = [];
    var url = "CallToControllerURL";

    $.getJSON(url, function(response) {
        $.each(response, function(i, item) {
            categorySeries .push(response[i].dateVal);
            dataSeries.push(response[i].count);
        });

        $('#chartDiv').highcharts({
            chart : {type : 'column'},
            title : {text : 'Date vs Count'},
            xAxis : {categories : categorySeries, crosshair : true},
            yAxis : {allowDecimals: false, min : 0, title : { text : 'Count'}},
            plotOptions : { column : {  pointPadding : 0.2, borderWidth : 0,    allowPointSelect: true  } },
            series : [ {name : 'Nbr of Records',data : dataSeries } ]
        });
    });
}

I want to be able to modify the color of bar for any day if the count is greater than a particular value, say 10.

This is how the json input to the function.

[{"id":3,"dateVal":"2015-11-12","count":6},{"id":2,"dateVal":"2015-11-11","count":8},{"id":1,"dateVal":"2015-11-10","count":5}]

Any suggestions how i can do this?

ContentLicense: CC BY-SA 4.0


问:
Vue and Prismic rich text: add event listener to a span node
The content of my Vue app is fetched from Prismic (an API CMS). I have a rich text block, some parts of which are wrapped inside span tags with a specific class. I want to get those span nodes with Vue and add to them an event listener.

With JS, this code would work:

```<code>var selectedSpanElements = document.querySelectorAll('.className');
selectedSpanElements[0].style.color = "red"
</code>```

But when I use this code in Vue, I can see that it works just a fraction of a second before Vue updates the DOM. I've tried using this code on mounted, beforeupdate, updated, ready hooks... Nothing has worked.

Update: Some hours later, I found that with the HTMLSerializer I can add HTML code to the span tag. But this is regular HTML, I cannot access to Vue methods.

答:
@Bruja
I was able to find a solution using a closure.  The folks at Prismic reminded/showed me.

Of note, per Phil Snow's comment above:  If you are using Nuxt you won't have access to Vue's functionality and will have to go old-school JS.

Here is an example where you can pass in component-level props, data, methods, etc... to the prismic htmlSerializer:

```<code><template>
  <div>
    <prismic-rich-text
      :field="data"
      :htmlSerializer="anotherHtmlSerializer((startNumber = list.start_number))"
    />
  </div>
</template>
</code>```

```<code>import prismicDOM from 'prismic-dom';

export default {
  methods: {
    anotherHtmlSerializer(startNumber = 1) {
      const Elements = prismicDOM.RichText.Elements;
      const that = this;

      return function(type, element, content, children) {
        // To add more elements and customizations use this as a reference:
        // https://prismic.io/docs/vuejs/beyond-the-api/html-serializer

        that.testMethod(startNumber);

        switch (type) {
          case Elements.oList:
            return `<ol start=${startNumber}>${children.join('')}</ol>`;
        }

        // Return null to stick with the default behavior for everything else
        return null;
      };
    },

    testMethod(startNumber) {
      console.log('test method here');
      console.log(startNumber);
    }
  }
};
</code>```

Body:
The content of my Vue app is fetched from Prismic (an API CMS). I have a rich text block, some parts of which are wrapped inside span tags with a specific class. I want to get those span nodes with Vue and add to them an event listener.

With JS, this code would work:

var selectedSpanElements = document.querySelectorAll('.className');
selectedSpanElements[0].style.color = "red"

But when I use this code in Vue, I can see that it works just a fraction of a second before Vue updates the DOM. I've tried using this code on mounted, beforeupdate, updated, ready hooks... Nothing has worked.

Update: Some hours later, I found that with the HTMLSerializer I can add HTML code to the span tag. But this is regular HTML, I cannot access to Vue methods.

Body:
@Bruja
I was able to find a solution using a closure.  The folks at Prismic reminded/showed me.

Of note, per Phil Snow's comment above:  If you are using Nuxt you won't have access to Vue's functionality and will have to go old-school JS.

Here is an example where you can pass in component-level props, data, methods, etc... to the prismic htmlSerializer:

<template>
  <div>
    <prismic-rich-text
      :field="data"
      :htmlSerializer="anotherHtmlSerializer((startNumber = list.start_number))"
    />
  </div>
</template>

import prismicDOM from 'prismic-dom';

export default {
  methods: {
    anotherHtmlSerializer(startNumber = 1) {
      const Elements = prismicDOM.RichText.Elements;
      const that = this;

      return function(type, element, content, children) {
        // To add more elements and customizations use this as a reference:
        // https://prismic.io/docs/vuejs/beyond-the-api/html-serializer

        that.testMethod(startNumber);

        switch (type) {
          case Elements.oList:
            return `<ol start=${startNumber}>${children.join('')}</ol>`;
        }

        // Return null to stick with the default behavior for everything else
        return null;
      };
    },

    testMethod(startNumber) {
      console.log('test method here');
      console.log(startNumber);
    }
  }
};


问:
Spring Boot on Tomcat 9 Fails to Map Controllers (404's)
My Spring boot application packaged as ROOT.war on tomcat9 using Java 11 appears to load successfully but fails to map the controllers. I can view every page by going right to the .jsp but my controller's map the URL's without .jsp. If I go to the mapped URL I get the standard 404 page.

This app works locally but expresses this behavior on my remote VM.

I've not seen this before and can't find anything relevant in my logs. I have another application with the exact same setup that works fine. What am I missing and/or what should I try next?

Here is my context file:

```<code><?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="true" path=""/>
</code>```

Using standard spring application setup:

```<code>@SpringBootApplication
public class Application extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
</code>```

And a basic request mapping and ModelAndView response:

```<code>@RestController
public class PageController extends BasePageController {
    private static final Logger LOGGER = LoggerFactory.getLogger(PageController.class);

    @Autowired       private Configuration configuration;

    @Autowired
    private OrderManager orderManager;

    @RequestMapping(value = "/", method=RequestMethod.GET)
    public ModelAndView indexSlash(HttpServletRequest arg0, HttpServletResponse arg1) {
</code>```

This works fine locally and for another app with the same setup, making me think its some minor version issue. I am using tomcat 9.0.34 and Java 11.0.7. There is nothing in my app log. Here is my catalina.out file after startup:

```<code>NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
31-May-2020 15:33:46.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.34
31-May-2020 15:33:46.748 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Apr 3 2020 12:02:52 UTC
31-May-2020 15:33:46.748 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.34.0
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.3.0-1022-azure
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-11-openjdk-amd64
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.7+10-post-Ubuntu-2ubuntu218.04
31-May-2020 15:33:46.750 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Ubuntu
31-May-2020 15:33:46.750 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat9
31-May-2020 15:33:46.751 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat9
31-May-2020 15:33:46.786 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
31-May-2020 15:33:46.788 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
31-May-2020 15:33:46.788 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat9
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat9
31-May-2020 15:33:46.792 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat9/temp
31-May-2020 15:33:46.792 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not $
31-May-2020 15:33:47.542 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
31-May-2020 15:33:47.606 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [1,342] milliseconds
31-May-2020 15:33:47.738 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
31-May-2020 15:33:47.744 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.34]
31-May-2020 15:33:47.800 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat9/webapps/ROOT.war]
31-May-2020 15:33:47.831 INFO [main] org.apache.catalina.startup.ExpandWar.expand An expanded directory [/usr/local/tomcat9/webapps/ROOT] was found with a last modified time that did not match the associated W$
31-May-2020 15:33:54.545 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs $
31-May-2020 15:33:55.095 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat9/webapps/ROOT.war] has finished in [7,295] ms
31-May-2020 15:33:55.100 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/host-manager]
31-May-2020 15:33:55.166 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/host-manager] has finished in [66] ms
31-May-2020 15:33:55.167 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/docs]
31-May-2020 15:33:55.207 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/docs] has finished in [40] ms
31-May-2020 15:33:55.208 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/examples]
31-May-2020 15:33:55.581 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/examples] has finished in [373] ms
31-May-2020 15:33:55.581 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/manager]
31-May-2020 15:33:55.625 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/manager] has finished in [43] ms
31-May-2020 15:33:55.633 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
31-May-2020 15:33:55.667 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [8,059] milliseconds
</code>```

答:
Okay, so as I expected, this was self inflicted. Turns out I had one dev machine set to build the project with Java 11 (same as my remote server) and another set to build the project with Java 14. The Java 14 version failed to deploy, go figure.

It's worth noting for others with the same symptoms that tomcat will explode and "deploy" a war that doesn't work so all the jsp, css, etc will show up yet the actual java code won't work. It also seems to be very limited in logging when this happen so you wont see anything indicating that it failed or why it failed.

To debug, I suggest using Nik's advise and set spring to debug level. I'd also suggest mirroring the dev environment exactly the same as the remote server to avoid these version alignment issues.

Body:
My Spring boot application packaged as ROOT.war on tomcat9 using Java 11 appears to load successfully but fails to map the controllers. I can view every page by going right to the .jsp but my controller's map the URL's without .jsp. If I go to the mapped URL I get the standard 404 page.

This app works locally but expresses this behavior on my remote VM.

I've not seen this before and can't find anything relevant in my logs. I have another application with the exact same setup that works fine. What am I missing and/or what should I try next?

Here is my context file:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="true" path=""/>

Using standard spring application setup:

@SpringBootApplication
public class Application extends SpringBootServletInitializer{

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

And a basic request mapping and ModelAndView response:

@RestController
public class PageController extends BasePageController {
    private static final Logger LOGGER = LoggerFactory.getLogger(PageController.class);

    @Autowired       private Configuration configuration;

    @Autowired
    private OrderManager orderManager;

    @RequestMapping(value = "/", method=RequestMethod.GET)
    public ModelAndView indexSlash(HttpServletRequest arg0, HttpServletResponse arg1) {

This works fine locally and for another app with the same setup, making me think its some minor version issue. I am using tomcat 9.0.34 and Java 11.0.7. There is nothing in my app log. Here is my catalina.out file after startup:

NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
31-May-2020 15:33:46.744 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.34
31-May-2020 15:33:46.748 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Apr 3 2020 12:02:52 UTC
31-May-2020 15:33:46.748 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.34.0
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            5.3.0-1022-azure
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-11-openjdk-amd64
31-May-2020 15:33:46.749 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           11.0.7+10-post-Ubuntu-2ubuntu218.04
31-May-2020 15:33:46.750 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Ubuntu
31-May-2020 15:33:46.750 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat9
31-May-2020 15:33:46.751 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat9
31-May-2020 15:33:46.786 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat9/conf/logging.properties
31-May-2020 15:33:46.787 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
31-May-2020 15:33:46.788 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
31-May-2020 15:33:46.788 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat9
31-May-2020 15:33:46.789 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat9
31-May-2020 15:33:46.792 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat9/temp
31-May-2020 15:33:46.792 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not $
31-May-2020 15:33:47.542 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
31-May-2020 15:33:47.606 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [1,342] milliseconds
31-May-2020 15:33:47.738 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
31-May-2020 15:33:47.744 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.34]
31-May-2020 15:33:47.800 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat9/webapps/ROOT.war]
31-May-2020 15:33:47.831 INFO [main] org.apache.catalina.startup.ExpandWar.expand An expanded directory [/usr/local/tomcat9/webapps/ROOT] was found with a last modified time that did not match the associated W$
31-May-2020 15:33:54.545 INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs $
31-May-2020 15:33:55.095 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat9/webapps/ROOT.war] has finished in [7,295] ms
31-May-2020 15:33:55.100 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/host-manager]
31-May-2020 15:33:55.166 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/host-manager] has finished in [66] ms
31-May-2020 15:33:55.167 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/docs]
31-May-2020 15:33:55.207 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/docs] has finished in [40] ms
31-May-2020 15:33:55.208 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/examples]
31-May-2020 15:33:55.581 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/examples] has finished in [373] ms
31-May-2020 15:33:55.581 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat9/webapps/manager]
31-May-2020 15:33:55.625 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat9/webapps/manager] has finished in [43] ms
31-May-2020 15:33:55.633 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
31-May-2020 15:33:55.667 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [8,059] milliseconds


问:
Displaying Unlimited Structure of Categories --> Subcategories --> etc?
I imagine this is a fairly common requirement for people when it comes to building any kind of application that relies on sorting and displaying data in categories - any CMS/Forums/Carts etc and I've been tearing my hair out trying to think of a way to show all categories and their children to no avail - the best I've managed is while loop within while loop (however many levels I think I may require) but this defeats the point of programming in my opinion, it needs to be effortlessly extensible.

So, given:

```<code>Category 1
-Sub cat
-Sub cat
--Sub sub cat
--- Sub sub cat
-- Sub sub cat
-Sub cat
Category 2
-Sub cat
-Sub cat
--Sub sub cat
---sub sub sub cat
----sub sub sub sub cat
-sub cat
Category 3
-Sub cat
</code>```

Database fields: ID Name ParentIDS

How would you go about echoing each of the categories in their hierarchy from a database?

I'd post my code, but obviously its massive, given the long-hand way of nesting loops.

I've thought about writing bits of code that find the 'depth' of the category tree but that still isn't cutting it.. ideas?

答:
The structure you're talking about is essentially a tree. Iterating over a tree is relatively simple if you use recursion. I don't know what database access code you're using, but you should be able to extrapolate accordingly from the following psuedocode:

```<code>function iterate_tree(arr) {
    foreach (item in arr) {
        print item;
        iterate_tree(item.children);
    }
}
</code>```

In english, that means print an item in the list, then print its children, and once all children (and their children) have printed, move on to the next item in the list.

Body:
I imagine this is a fairly common requirement for people when it comes to building any kind of application that relies on sorting and displaying data in categories - any CMS/Forums/Carts etc and I've been tearing my hair out trying to think of a way to show all categories and their children to no avail - the best I've managed is while loop within while loop (however many levels I think I may require) but this defeats the point of programming in my opinion, it needs to be effortlessly extensible.

So, given:

Category 1
-Sub cat
-Sub cat
--Sub sub cat
--- Sub sub cat
-- Sub sub cat
-Sub cat
Category 2
-Sub cat
-Sub cat
--Sub sub cat
---sub sub sub cat
----sub sub sub sub cat
-sub cat
Category 3
-Sub cat

Database fields: ID Name ParentIDS

How would you go about echoing each of the categories in their hierarchy from a database?

I'd post my code, but obviously its massive, given the long-hand way of nesting loops.

I've thought about writing bits of code that find the 'depth' of the category tree but that still isn't cutting it.. ideas?

Body:
The structure you're talking about is essentially a tree. Iterating over a tree is relatively simple if you use recursion. I don't know what database access code you're using, but you should be able to extrapolate accordingly from the following psuedocode:

function iterate_tree(arr) {
    foreach (item in arr) {
        print item;
        iterate_tree(item.children);
    }
}

In english, that means print an item in the list, then print its children, and once all children (and their children) have printed, move on to the next item in the list.


问:
How to limit width of multiple TextFields inside a Column? Wrapping the latter with a SizedBox doesn't work
This is my tree:

Scaffold(-> Column(-> Expanded(-> ListView(-> Column(-> TextFields)))));

I want to limit the width of these TextFields (say, to 200px), but using SizedBox/Container/ConstrainedBox and setting a width/maxWidth on the Column isn't working; I have to wrap each individual TextField with a SizedBox for it to work- which adds a lot of fluff to my code.

Is there a better way to do this?

答:
Add Container at the top and give it width:200

```<code>Scaffold(-> Container(width:200 ->Column(-> Expanded(-> ListView(-> Column(-> TextFields)))));
</code>```

Body:
Add Container at the top and give it width:200

Scaffold(-> Container(width:200 ->Column(-> Expanded(-> ListView(-> Column(-> TextFields)))));


问:
Reset rolling calculation when category changes in DF
I have a df that looks like this:

```<code>    Category    Product     Location    Date formatted  Volume
0   A           TYPE_B      Central     2019-04-01      13.0
1   A           TYPE_B      Central     2019-05-01      13.0
2   A           TYPE_B      Central     2019-06-01      12.0
3   A           TYPE_B      Central     2019-07-01      14.0
4   A           TYPE_B      Central     2019-08-01      14.0
5   A           TYPE_B      Central     2019-09-01      13.0
6   A           TYPE_B      Central     2019-10-01      14.0
7   A           TYPE_B      Central     2019-11-01      13.0
8   A           TYPE_B      Central     2019-12-01      13.0
9   A           TYPE_B      Central     2020-01-01      13.0
10  A           TYPE_B      Central     2020-02-01      13.0
11  A           TYPE_B      Central     2020-03-01      15.0
12  A           TYPE_B      East        2019-04-01      21.0
13  A           TYPE_B      East        2019-05-01      20.0
14  A           TYPE_B      East        2019-06-01      18.0
15  A           TYPE_B      East        2019-07-01      21.0
16  A           TYPE_B      East        2019-08-01      22.0
17  A           TYPE_B      East        2019-09-01      19.0
18  A           TYPE_B      East        2019-10-01      20.0
19  A           TYPE_B      East        2019-11-01      20.0
20  A           TYPE_B      East        2019-12-01      19.0
21  A           TYPE_B      East        2020-01-01      20.0
22  A           TYPE_B      East        2020-02-01      20.0
23  A           TYPE_B      East        2020-03-01      27.0
</code>```

I'm trying to calculate the rolling 3 month volume for each location from the start ("2019-04-01") and end ("2020-03-01) time frames for the data, so far I am using the following code:

```<code>df['Rolling_3_] = df.loc.iloc[:,4].rolling(window=4).mean()
</code>```

This gives me my rolling 3 month mean for the entire dataframe. However, does anyone know how I can restart the rolling month calculation so that when it reaches another "Location" such as "East" it will calculate the rolling 3 months average for that location and move on to the next location, restarting the calculation? In essence calculating the rolling 3 months for the entire dataset, but with the values being applicable to the location. Is there a way I could possibly do this with the date itself? such as when "2019-04-01" appears again the calculation restarts.

Many thanks for any help/suggestions in advance!

Kind regards,

答:
You can do a groupby:

```<code>df.groupby(['Category','Product','Location']).Volume.rolling(3).mean()
</code>```

gives you:

```<code>Category  Product  Location
A         TYPE_B   Central   0           NaN
                             1           NaN
                             2     12.666667
                             3     13.000000
                             4     13.333333
                             5     13.666667
                             6     13.666667
                             7     13.333333
                             8     13.333333
                             9     13.000000
                             10    13.000000
                             11    13.666667
                   East      12          NaN
                             13          NaN
                             14    19.666667
                             15    19.666667
                             16    20.333333
                             17    20.666667
                             18    20.333333
                             19    19.666667
                             20    19.666667
                             21    19.666667
                             22    19.666667
                             23    22.333333
Name: Volume, dtype: float64
</code>```

To get this into your dataframe, you need to pass the underlying numpy array due to the difference of index

```<code># notice `values` at the end
df['rolling_mean'] = df.groupby(['Category','Product','Location']).Volume.rolling(3).mean().values
</code>```

Body:
I have a df that looks like this:

    Category    Product     Location    Date formatted  Volume
0   A           TYPE_B      Central     2019-04-01      13.0
1   A           TYPE_B      Central     2019-05-01      13.0
2   A           TYPE_B      Central     2019-06-01      12.0
3   A           TYPE_B      Central     2019-07-01      14.0
4   A           TYPE_B      Central     2019-08-01      14.0
5   A           TYPE_B      Central     2019-09-01      13.0
6   A           TYPE_B      Central     2019-10-01      14.0
7   A           TYPE_B      Central     2019-11-01      13.0
8   A           TYPE_B      Central     2019-12-01      13.0
9   A           TYPE_B      Central     2020-01-01      13.0
10  A           TYPE_B      Central     2020-02-01      13.0
11  A           TYPE_B      Central     2020-03-01      15.0
12  A           TYPE_B      East        2019-04-01      21.0
13  A           TYPE_B      East        2019-05-01      20.0
14  A           TYPE_B      East        2019-06-01      18.0
15  A           TYPE_B      East        2019-07-01      21.0
16  A           TYPE_B      East        2019-08-01      22.0
17  A           TYPE_B      East        2019-09-01      19.0
18  A           TYPE_B      East        2019-10-01      20.0
19  A           TYPE_B      East        2019-11-01      20.0
20  A           TYPE_B      East        2019-12-01      19.0
21  A           TYPE_B      East        2020-01-01      20.0
22  A           TYPE_B      East        2020-02-01      20.0
23  A           TYPE_B      East        2020-03-01      27.0

I'm trying to calculate the rolling 3 month volume for each location from the start ("2019-04-01") and end ("2020-03-01) time frames for the data, so far I am using the following code:

df['Rolling_3_] = df.loc.iloc[:,4].rolling(window=4).mean()

This gives me my rolling 3 month mean for the entire dataframe. However, does anyone know how I can restart the rolling month calculation so that when it reaches another "Location" such as "East" it will calculate the rolling 3 months average for that location and move on to the next location, restarting the calculation? In essence calculating the rolling 3 months for the entire dataset, but with the values being applicable to the location. Is there a way I could possibly do this with the date itself? such as when "2019-04-01" appears again the calculation restarts.

Many thanks for any help/suggestions in advance!

Kind regards,

Body:
You can do a groupby:

df.groupby(['Category','Product','Location']).Volume.rolling(3).mean()

gives you:

Category  Product  Location
A         TYPE_B   Central   0           NaN
                             1           NaN
                             2     12.666667
                             3     13.000000
                             4     13.333333
                             5     13.666667
                             6     13.666667
                             7     13.333333
                             8     13.333333
                             9     13.000000
                             10    13.000000
                             11    13.666667
                   East      12          NaN
                             13          NaN
                             14    19.666667
                             15    19.666667
                             16    20.333333
                             17    20.666667
                             18    20.333333
                             19    19.666667
                             20    19.666667
                             21    19.666667
                             22    19.666667
                             23    22.333333
Name: Volume, dtype: float64

To get this into your dataframe, you need to pass the underlying numpy array due to the difference of index

# notice `values` at the end
df['rolling_mean'] = df.groupby(['Category','Product','Location']).Volume.rolling(3).mean().values


问:
Using named Navigator from different widgets in flutter?
I need to navigate to a widget(screen) using named navigation from another widget(screen). This is the body of MyHomePage Widget

```<code>body: Navigator(
  key: _navigatorKey,
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) {
    WidgetBuilder builder;

    switch (settings.name) {
      case '/':
        builder = (BuildContext context) => UIHomePage();
        break;
      case '/cart':
        builder = (BuildContext context) => UICartPage();
        break;
      case '/account':
        builder = (BuildContext context) => UIAccountPage();
        break;
      default:
        throw Exception('Invalid route: ${settings.name}');
    }

    return MaterialPageRoute(builder: builder, settings: settings, );
  },
),
</code>```

I can toggle these PageRoutes from the bottomNavigationBar with _navigatorKey.currentState.pushNamed(routeNames[tabItem]) where routeNames is a list of Strings ['/', '/cart', '/account']. This works fine.

Now, from UIAccountPage(), where I have a ListTile named 'Cart', I wish to navigate to the UICartPage on tapping that particular tile. I also have several other tiles that I wish to use to navigate to other widgets (screens).

To achieve this, do I have to expand the onGenerateRoute in MyHomePage to accommodate other routes or I have to create another custom Navigator somewhere? I am at odds. If somebody could guide with a simple illustration that would be awesome.

Thanks

Edit: Also I have no idea what setting does in Navigator and _navigatorKey is final _navigatorKey = GlobalKey<NavigatorState>()

答:
i'm pretty new using Flutter but i've this implementation an works fine for routes.

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Temp Detector',
      initialRoute: '/',
      routes: {
        '/': (context) => AuthScreen(),
        '/register': (context) => SignInScreen(),
        '/login': (context) => LoginScreen(),
        '/home': (context) => HomeScreen(),
        '/config': (context) => ConfigScreen(),
      },
    );
  }
}

```

<p>And when i try to go to another view i use:</p>

<pre class="lang-dart prettyprint-override"><code>Navigator.pushReplacementNamed(context, '/home');
</code>```

Where the 2nd param is the name defined in the routes.

Hope it does help you!

Body:
I need to navigate to a widget(screen) using named navigation from another widget(screen). This is the body of MyHomePage Widget

body: Navigator(
  key: _navigatorKey,
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) {
    WidgetBuilder builder;

    switch (settings.name) {
      case '/':
        builder = (BuildContext context) => UIHomePage();
        break;
      case '/cart':
        builder = (BuildContext context) => UICartPage();
        break;
      case '/account':
        builder = (BuildContext context) => UIAccountPage();
        break;
      default:
        throw Exception('Invalid route: ${settings.name}');
    }

    return MaterialPageRoute(builder: builder, settings: settings, );
  },
),

I can toggle these PageRoutes from the bottomNavigationBar with _navigatorKey.currentState.pushNamed(routeNames[tabItem]) where routeNames is a list of Strings ['/', '/cart', '/account']. This works fine.

Now, from UIAccountPage(), where I have a ListTile named 'Cart', I wish to navigate to the UICartPage on tapping that particular tile. I also have several other tiles that I wish to use to navigate to other widgets (screens).

To achieve this, do I have to expand the onGenerateRoute in MyHomePage to accommodate other routes or I have to create another custom Navigator somewhere? I am at odds. If somebody could guide with a simple illustration that would be awesome.

Thanks

Edit: Also I have no idea what setting does in Navigator and _navigatorKey is final _navigatorKey = GlobalKey<NavigatorState>()

Body:
i'm pretty new using Flutter but i've this implementation an works fine for routes.

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Temp Detector',
      initialRoute: '/',
      routes: {
        '/': (context) => AuthScreen(),
        '/register': (context) => SignInScreen(),
        '/login': (context) => LoginScreen(),
        '/home': (context) => HomeScreen(),
        '/config': (context) => ConfigScreen(),
      },
    );
  }
}

And when i try to go to another view i use:

Navigator.pushReplacementNamed(context, '/home');

Where the 2nd param is the name defined in the routes.

Hope it does help you!


问:
how i can generate arandom password with this filter woocommerce
thanks for help me.
Then, i try a generate a random password with this code, but at present generate a date.
I neet generate a random password.

thanks

```<code>function changePassword($pass) {
        $password = date('Y');
        return $password;
}
add_filter('random_password', 'changePassword');
</code>```

答:
You can try this way:

```<code>function changePassword( $pass ) {
    return wp_generate_password();
}
add_filter( 'random_password', 'changePassword' );
</code>```

Hope it's help you. Check please the documentation.

Body:
thanks for help me.
Then, i try a generate a random password with this code, but at present generate a date.
I neet generate a random password.

thanks

function changePassword($pass) {
        $password = date('Y');
        return $password;
}
add_filter('random_password', 'changePassword');

Body:
You can try this way:

function changePassword( $pass ) {
    return wp_generate_password();
}
add_filter( 'random_password', 'changePassword' );

Hope it's help you. Check please the documentation.


问:
do we need write try catch when we want get data from database in laravel?
I have developed many APIs in Laravel and I want to know for example if I want to have a list of posts in my /api/posts route I should write codes in try catch block or it does not needed?</p>

答:
What I suggest is that you work with transactions and try catch hand, for example:

```<code>use DB;

    try {
        DB::beginTransaction();

        // your code, wherever you want

        DB::commit(); // commit if everything is ok.

        return $somethin; //return the data.

    } catch (\Throwable $th) {
        \Log::error($th);
        DB::rollBack(); // do a rollback in your db.
        return $this->sendError($th->getMessage(), 500); //send custom error or anything
    }
</code>```

for more info, the docs.

Body:
What I suggest is that you work with transactions and try catch hand, for example:

use DB;

    try {
        DB::beginTransaction();

        // your code, wherever you want

        DB::commit(); // commit if everything is ok.

        return $somethin; //return the data.

    } catch (\Throwable $th) {
        \Log::error($th);
        DB::rollBack(); // do a rollback in your db.
        return $this->sendError($th->getMessage(), 500); //send custom error or anything
    }

for more info, the docs.


问:
Set background color of a specific control
I have searched the net looking for a way to set background color a dialog control.

I have managed to do this with this code:

```<code>case WM_CTLCOLORSTATIC:
{
    HDC hdcStatic = (HDC) wParam;
    SetTextColor(hdcStatic, RGB(255,255,255));
    SetBkColor(hdcStatic, RGB(0,0,0));

    if (hbrBkgnd == NULL)
    {
        hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
    }
    return (INT_PTR)hbrBkgnd;
}
</code>```

However, what I am actually looking for is to color only a specific static control, not all the static controls I have in my dialog. Is there anyway to do this? Perhaps set the hdc to something using GetDlgItem(hdlg,"IDC_MYCONTROL") ?

-- UPDATE

After the suggestions I ended up with this :

```<code>case WM_CTLCOLORSTATIC:
{
    HDC hdcStatic = (HDC) lParam;
    HWND hWnd =  (HWND)lParam;
    HWND dlg =GetDlgItem(hDlg, IDC_STATIC2);
    if (hWnd == dlg)
    {
        SetTextColor(hdcStatic, RGB(255,255,255));
        SetBkColor(hdcStatic, RGB(0,0,0));
    }
    if (hbrBkgnd == NULL)
    {
        hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
    }
    return (INT_PTR)hbrBkgnd;
}
</code>```

And it seems that even if SetBkColor is run nothing changes on the dialog, leading on the wierd problem described below.

答:
The HWND is passed to the dialog proc so you could;</p>

```<code> HWND hWnd = (HWND) lParam;
 if (hWnd == GetDlgItem(hdlg, "IDC_MYCONTROL")) {
     ...
</code>```

Body:
I have searched the net looking for a way to set background color a dialog control.

I have managed to do this with this code:

case WM_CTLCOLORSTATIC:
{
    HDC hdcStatic = (HDC) wParam;
    SetTextColor(hdcStatic, RGB(255,255,255));
    SetBkColor(hdcStatic, RGB(0,0,0));

    if (hbrBkgnd == NULL)
    {
        hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
    }
    return (INT_PTR)hbrBkgnd;
}

However, what I am actually looking for is to color only a specific static control, not all the static controls I have in my dialog. Is there anyway to do this? Perhaps set the hdc to something using GetDlgItem(hdlg,"IDC_MYCONTROL") ?

-- UPDATE

After the suggestions I ended up with this :

case WM_CTLCOLORSTATIC:
{
    HDC hdcStatic = (HDC) lParam;
    HWND hWnd =  (HWND)lParam;
    HWND dlg =GetDlgItem(hDlg, IDC_STATIC2);
    if (hWnd == dlg)
    {
        SetTextColor(hdcStatic, RGB(255,255,255));
        SetBkColor(hdcStatic, RGB(0,0,0));
    }
    if (hbrBkgnd == NULL)
    {
        hbrBkgnd = CreateSolidBrush(RGB(0,0,0));
    }
    return (INT_PTR)hbrBkgnd;
}

And it seems that even if SetBkColor is run nothing changes on the dialog, leading on the wierd problem described below.

Body:
The HWND is passed to the dialog proc so you could;

 HWND hWnd = (HWND) lParam;
 if (hWnd == GetDlgItem(hdlg, "IDC_MYCONTROL")) {
     ...


问:
Detect if mouse button is down
I am new to c++ and I am trying to activate a line of code only when the left mouse button is held down. In this example, my code works but it seems that it just toggles it. When I click, it spams the H key then, when I click again, it stops.

Currently I have this code:

```<code>if ((GetKeyState(VK_LBUTTON)))
{
    keybd_event(VkKeyScan('H'),0,0,0);
    Sleep ( 30 );
}
</code>```

Edit:

I have inside the function:

```<code>int WINAPI WinMain ( HINSTANCE hInst, HINSTANCE P, LPSTR CMD, int nShowCmd );
</code>```

答:
Use the below to detect left mouse button press

```<code>if(GetAsyncKeyState(VK_LBUTTON)){
   //your code controls here
 }
</code>```

You can find more controls here : https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate

Also if the GetAsyncKeyState(VK_LBUTTON)shows a syntax error, try including winuser.h by adding #include <winuser.h> in the includes of your code.

Here is an example

```<code>if(GetKeyState(VK_LBUTTON))
    {   //finding clicked position
        HWND hWnd = FindWindowA(0,("Motion Paths"));
        ::GetWindowThreadProcessId(hWnd,&pid);
        if (hWnd) { cout << "Found" << endl;}

            POINT p;
            GetCursorPos(&p);
            if (ScreenToClient(hWnd, &p))
            {
                int mouseX = p.x;
                int mouseY = p.y;
                cout<< p.x << " "<< p.y <<endl;
            }
    }
</code>```

Title: Detect if mouse button is down

Body:
I am new to c++ and I am trying to activate a line of code only when the left mouse button is held down. In this example, my code works but it seems that it just toggles it. When I click, it spams the H key then, when I click again, it stops.

Currently I have this code:

if ((GetKeyState(VK_LBUTTON)))
{
    keybd_event(VkKeyScan('H'),0,0,0);
    Sleep ( 30 );
}

Edit:

I have inside the function:

int WINAPI WinMain ( HINSTANCE hInst, HINSTANCE P, LPSTR CMD, int nShowCmd );

Body:
Use the below to detect left mouse button press

if(GetAsyncKeyState(VK_LBUTTON)){
   //your code controls here
 }

You can find more controls here : https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate

Also if the GetAsyncKeyState(VK_LBUTTON)shows a syntax error, try including winuser.h by adding #include <winuser.h> in the includes of your code.

Here is an example

if(GetKeyState(VK_LBUTTON))
    {   //finding clicked position
        HWND hWnd = FindWindowA(0,("Motion Paths"));
        ::GetWindowThreadProcessId(hWnd,&pid);
        if (hWnd) { cout << "Found" << endl;}

            POINT p;
            GetCursorPos(&p);
            if (ScreenToClient(hWnd, &p))
            {
                int mouseX = p.x;
                int mouseY = p.y;
                cout<< p.x << " "<< p.y <<endl;
            }
    }


问:
Owned Storage vs Referenced Storage
Looking at this page in the Snowflake docs: https://docs.snowflake.com/en/user-guide/tables-storage-considerations.html#owned-storage-vs-referenced-storage ...

If T2 is cloned from T1 and then data is changed in T2, T2 is the owner of that changed data.

If T3 and T4 are both cloned from T2 and then T2 is dropped, is the data that T2 owned then duplicated between T3 and T4 and both own their copies of that data?

If not, how does this work?

Thanks

答:
I assume you are referring to which table the storage of the data is associated to.  When a table is dropped, the storage elements are not deleted unless no other tables (clones) reference that data.  The only thing that is deleted is the reference to that data.  So, if you have T3 and T4 as clones to T2, and then T2 is dropped, T3 and T4 will still reference the micropartitions that were contained in T2.  They are not duplicated.

Ownership of the micropartitions is really just for accounting the storage to a particular table.  In your example, the T2 micropartitions will have the ownership transferred to whichever clone was created first (T3 or T4, not both).  This is all a metadata operation in Snowflake that happens behind the scenes.

Title: Owned Storage vs Referenced Storage


答:
1, I think you should be try BottomNavigationBar with PageView or TabView.

2, With your issue, you can try options create a callback for UIAccountPage:

```<code>  case '/account':
    builder = (BuildContext context) => UIAccountPage(onTapCart: () {
      _navigatorKey.currentState.pushNamed('/cart');
    });
    break;
</code>```

And UIAccountPage

```<code>class UIAccountPage extends StatelessWidget {

  VoidCallback onTapCart;

  UIAccountPage({this.onTapCart});

  @override
  Widget build(BuildContext context) {
    .....
  }

}
</code>```

Title: Using named Navigator from different widgets in flutter?

Body:
1, I think you should be try BottomNavigationBar with PageView or TabView.

2, With your issue, you can try options create a callback for UIAccountPage:

  case '/account':
    builder = (BuildContext context) => UIAccountPage(onTapCart: () {
      _navigatorKey.currentState.pushNamed('/cart');
    });
    break;

And UIAccountPage

class UIAccountPage extends StatelessWidget {

  VoidCallback onTapCart;

  UIAccountPage({this.onTapCart});

  @override
  Widget build(BuildContext context) {
    .....
  }

}


问:
Unable to Get DHCP Lease - dhcps: send_offer>>udp_sendto result ffffffff
When connecting to an ESP32 in softAP mode from an ESP32 client, the client connects and disconnects just fine for a while. Eventually, the AP will show the following error:

dhcps: send_offer>>udp_sendto result ffffffff

The client connects but doesn't get a lease. If I try to connect from another device, like my
iPhone, it doesn't get a lease either. If I set the client as static, it works just fine even after the server stops responding to DHCP request. Stopping and starting the DHCP server doesn't fix it.

I'm using AsyncTCP (me-no-dev Oct 17, 2019 version) on the server. I'm using the 1.12.2 Espressif 32 board library in PlatformIO. (Didn't work with 1.12.1 either)

Any idea why I'm unable to obtain a lease? Rebooting the AP does fix the issue so it doesn't appear to be an issue with the client.

答:
I ran out of heap space. In AsyncTCP you have to explicitly free and delete the point.

https://gitter.im/espressif/arduino-esp32?at=5d6d213329dba2421ceea2c8


问:
Best way to check the PDF file is corrupt using python
I try to check the PDF files are corrupted in windows environment and come up with following python code.

Just want to check is it the best way to check corrupted PDF files or is there any other easy way?

Note: C:\Temp\python\sample-map (1).pdf is the corrupted PDF file

Here is the sample code

```<code>import os
import subprocess
import re
from subprocess import Popen, PIPE

def checkFile(fullfile):
    proc=subprocess.Popen(["file", "-b", fullfile], shell=True, stdout=PIPE, stderr=PIPE, bufsize=0)
    # -b, --brief : do not prepend filenames to output lines
    out, err = proc.communicate()
    exitcode = proc.returncode
    return exitcode, out, err

def searchFiles(dirpath):
    pwdpath=os.path.dirname(os.path.realpath(__file__))
    print("running path : %s" %pwdpath )
    if os.access(dirpath, os.R_OK):
        print("Path %s validation OK \n" %dirpath)
        listfiles=os.listdir(dirpath)
        for files in listfiles:
            fullfile=os.path.join(dirpath, files)
            if os.access(fullfile, os.R_OK):
                code, out, error = checkFile(fullfile)
                if str(code) !="0" or str(error, "utf-8") != "" or re.search("^(?!PDF(\s)).*", str(out,'utf-8')):
                    print("ERROR " + fullfile+"\n################")
                else:
                    print("OK " + fullfile+"\n################")
            else:
                print("$s : File not readable" %fullfile)
    else:
        print("Path is not valid")

if __name__ == "__main__":
    searchFiles('C:\Temp\python')
</code>```

sample output :

```<code>$ "C:/Program Files (x86)/Python37-32/python.exe" c:/Users/myuser/python/check_pdf_file.py
running path : c:\Users\myuser\python
Path C:\Temp\python validation OK

OK C:\Temp\python\Induction Guide.pdf
################
ERROR C:\Temp\python\sample-map (1).pdf
################
OK C:\Temp\python\sample-map.pdf
################
</code>```

答:
I think you can use PyPDF2 module.

pip install pypdf2

The code is as follows.

```<code>from PyPDF2 import PdfFileReader
import os

def checkFile(fullfile):
    with open(fullfile, 'rb') as f:
        try:
            pdf = PdfFileReader(f)
            info = pdf.getDocumentInfo()
            if info:
                return True
            else:
                return False
        except:
            return False

def searchFiles(dirpath):
    pwdpath = os.path.dirname(os.path.realpath(__file__))
    print("running path : %s" %pwdpath )
    if os.access(dirpath, os.R_OK):
        print("Path %s validation OK \n" %dirpath)
        listfiles = os.listdir(dirpath)
        for f in listfiles:
            fullfile = os.path.join(dirpath, f)
            if checkFile(fullfile):
                print("OK " + fullfile + "\n################")
            else:
                print("ERROR " + fullfile + "\n################")
    else:
        print("Path is not valid")

if __name__ == "__main__":
    searchFiles('C:\Temp\python')
</code>```

I tried to match your coding style.

I think this code can also be used on MacOS or Linux.

Body:
I try to check the PDF files are corrupted in windows environment and come up with following python code.

Just want to check is it the best way to check corrupted PDF files or is there any other easy way?

Note: C:\Temp\python\sample-map (1).pdf is the corrupted PDF file

Here is the sample code

import os
import subprocess
import re
from subprocess import Popen, PIPE

def checkFile(fullfile):
    proc=subprocess.Popen(["file", "-b", fullfile], shell=True, stdout=PIPE, stderr=PIPE, bufsize=0)
    # -b, --brief : do not prepend filenames to output lines
    out, err = proc.communicate()
    exitcode = proc.returncode
    return exitcode, out, err

def searchFiles(dirpath):
    pwdpath=os.path.dirname(os.path.realpath(__file__))
    print("running path : %s" %pwdpath )
    if os.access(dirpath, os.R_OK):
        print("Path %s validation OK \n" %dirpath)
        listfiles=os.listdir(dirpath)
        for files in listfiles:
            fullfile=os.path.join(dirpath, files)
            if os.access(fullfile, os.R_OK):
                code, out, error = checkFile(fullfile)
                if str(code) !="0" or str(error, "utf-8") != "" or re.search("^(?!PDF(\s)).*", str(out,'utf-8')):
                    print("ERROR " + fullfile+"\n################")
                else:
                    print("OK " + fullfile+"\n################")
            else:
                print("$s : File not readable" %fullfile)
    else:
        print("Path is not valid")

if __name__ == "__main__":
    searchFiles('C:\Temp\python')

sample output :

$ "C:/Program Files (x86)/Python37-32/python.exe" c:/Users/myuser/python/check_pdf_file.py
running path : c:\Users\myuser\python
Path C:\Temp\python validation OK

OK C:\Temp\python\Induction Guide.pdf
################
ERROR C:\Temp\python\sample-map (1).pdf
################
OK C:\Temp\python\sample-map.pdf
################

Body:
I think you can use PyPDF2 module.

pip install pypdf2

The code is as follows.

from PyPDF2 import PdfFileReader
import os

def checkFile(fullfile):
    with open(fullfile, 'rb') as f:
        try:
            pdf = PdfFileReader(f)
            info = pdf.getDocumentInfo()
            if info:
                return True
            else:
                return False
        except:
            return False

def searchFiles(dirpath):
    pwdpath = os.path.dirname(os.path.realpath(__file__))
    print("running path : %s" %pwdpath )
    if os.access(dirpath, os.R_OK):
        print("Path %s validation OK \n" %dirpath)
        listfiles = os.listdir(dirpath)
        for f in listfiles:
            fullfile = os.path.join(dirpath, f)
            if checkFile(fullfile):
                print("OK " + fullfile + "\n################")
            else:
                print("ERROR " + fullfile + "\n################")
    else:
        print("Path is not valid")

if __name__ == "__main__":
    searchFiles('C:\Temp\python')

I tried to match your coding style.

I think this code can also be used on MacOS or Linux.


问:
How can I fix a time delay on my Table Viewcontroller?
I created a note app. The NotizenViewControllerArchive save the note and with the NotizenViewControllerAdd can you add new notes.

There is a third Viewcontroller, on this I can visit the other two views, but after I switched (with a button) from the third Viewcontroller to NotizenViewControllerArchive there is a time delay, a short moment who I can't see my notes how can I fix that so the notes shows immediately?.

I tried for a long time to fix it but I don't know how, I put the whole code in because I don't know where the problem is. Thanks for your help

NotizenViewControllerArchive

```<code>import UIKit

class NotizenViewControllerArchive: UIViewController, UITableViewDelegate, UITableViewDataSource {

  @IBOutlet weak var table: UITableView!

  var items:[String] = []
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")

    let backgroundView = UIView()
    backgroundView.backgroundColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1)
    cell.selectedBackgroundView = backgroundView

    cell.textLabel?.text = items[indexPath.row]
    return cell

  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

  override func viewDidAppear(_ animated: Bool) {
    let itemObject = UserDefaults.standard.object(forKey: "items")

    if let tempItems = itemObject as? [String] {
      items = tempItems
    }

    table.reloadData()
  }

  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCell.EditingStyle.delete {

      items.remove(at: indexPath.row)
      tableView.reloadData()
      UserDefaults.standard.set(items, forKey: "items")

    }
  }
}
</code>```

NotizenViewControllerAdd

```<code>import UIKit

class NotizenViewControllerAdd: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var itemTextField: UITextField!

  @IBAction func ad(_ sender: UIButton) {
    let itemObject = UserDefaults.standard.object(forKey: "items")

    var items:[String]

    if let tempItems = itemObject as? [String] {
      items = tempItems
      items.append(itemTextField.text!)
      print("items")
    } else {
      items = [itemTextField.text!]
    }

    UserDefaults.standard.set(items, forKey: "items")
    itemTextField.text = ""
  }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
  }

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    return true
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }
}

</code>```

答:
Try moving the code from viewDidAppear to viewWillAppear or viewDidLoad on your NotizenViewControllerArchive.
The code inside the viewDidAppear will only execute after the view is already on screen for the user (hence the name)</p>

Body:
I created a note app. The NotizenViewControllerArchive save the note and with the NotizenViewControllerAdd can you add new notes.

There is a third Viewcontroller, on this I can visit the other two views, but after I switched (with a button) from the third Viewcontroller to NotizenViewControllerArchive there is a time delay, a short moment who I can't see my notes how can I fix that so the notes shows immediately?.

I tried for a long time to fix it but I don't know how, I put the whole code in because I don't know where the problem is. Thanks for your help

NotizenViewControllerArchive

import UIKit

class NotizenViewControllerArchive: UIViewController, UITableViewDelegate, UITableViewDataSource {

  @IBOutlet weak var table: UITableView!

  var items:[String] = []
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return items.count
  }

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCell.CellStyle.default, reuseIdentifier: "Cell")

    let backgroundView = UIView()
    backgroundView.backgroundColor = UIColor.init(red: 48/255, green: 173/255, blue: 99/255, alpha: 1)
    cell.selectedBackgroundView = backgroundView

    cell.textLabel?.text = items[indexPath.row]
    return cell

  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

  override func viewDidAppear(_ animated: Bool) {
    let itemObject = UserDefaults.standard.object(forKey: "items")

    if let tempItems = itemObject as? [String] {
      items = tempItems
    }

    table.reloadData()
  }

  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == UITableViewCell.EditingStyle.delete {

      items.remove(at: indexPath.row)
      tableView.reloadData()
      UserDefaults.standard.set(items, forKey: "items")

    }
  }
}

NotizenViewControllerAdd

import UIKit

class NotizenViewControllerAdd: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var itemTextField: UITextField!

  @IBAction func ad(_ sender: UIButton) {
    let itemObject = UserDefaults.standard.object(forKey: "items")

    var items:[String]

    if let tempItems = itemObject as? [String] {
      items = tempItems
      items.append(itemTextField.text!)
      print("items")
    } else {
      items = [itemTextField.text!]
    }

    UserDefaults.standard.set(items, forKey: "items")
    itemTextField.text = ""
  }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    self.view.endEditing(true)
  }

  func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    return true
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }
}


问:
Unable to debug Blazor Webassembly
I have not been able to debug ever since I started using the Blazor webassembly a few weeks ago. I have looked at the ms docs: https://learn.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-3.1
and looked at some videos and All look well.  I have created a new app from scratch and still no change.

When looking at the breakboint it states : breakpoint set but not bound yet

On the server project it includes:

```<code><PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.0-preview5.20216.8" />
</code>```

And the launch settings profile is set with the inspectUri

```<code>"profiles": {
      "IIS Express": {
        "commandName": "IISExpress",
        "launchBrowser": true,
        "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      },
      "TestDebugging.Server": {
        "commandName": "Project",
        "launchBrowser": true,
        "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
        "applicationUrl": "https://localhost:5001;http://localhost:5000",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      }
    }
</code>```

On Client project It includes:

```<code> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0-preview5.20216.8" />
 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0-preview5.20216.8" PrivateAssets="all" />
 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0-preview5.20216.8" PrivateAssets="all" />
 <PackageReference Include="System.Net.Http.Json" Version="3.2.0-preview5.20210.3" />
</code>```

Microsoft Visual Studio Professional 2019 Version 16.5.0
VisualStudio.16.Release/16.5.0+29911.84 Microsoft .NET Framework
Version 4.8.03752

Installed Version: Professional

Chrome Version: Version 80.0.3987.132 (Official Build) (64-bit)

答: Upgrade VS to 16.6 or 16.7-preview1 </p>

Title: Unable to debug Blazor Webassembly

Body:
I have not been able to debug ever since I started using the Blazor webassembly a few weeks ago. I have looked at the ms docs: https://learn.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-3.1
and looked at some videos and All look well.  I have created a new app from scratch and still no change.

When looking at the breakboint it states : breakpoint set but not bound yet

On the server project it includes:

<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.0-preview5.20216.8" />

And the launch settings profile is set with the inspectUri

"profiles": {
      "IIS Express": {
        "commandName": "IISExpress",
        "launchBrowser": true,
        "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      },
      "TestDebugging.Server": {
        "commandName": "Project",
        "launchBrowser": true,
        "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
        "applicationUrl": "https://localhost:5001;http://localhost:5000",
        "environmentVariables": {
          "ASPNETCORE_ENVIRONMENT": "Development"
        }
      }
    }

On Client project It includes:

 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0-preview5.20216.8" />
 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0-preview5.20216.8" PrivateAssets="all" />
 <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0-preview5.20216.8" PrivateAssets="all" />
 <PackageReference Include="System.Net.Http.Json" Version="3.2.0-preview5.20210.3" />

Microsoft Visual Studio Professional 2019 Version 16.5.0
VisualStudio.16.Release/16.5.0+29911.84 Microsoft .NET Framework
Version 4.8.03752

Installed Version: Professional

Chrome Version: Version 80.0.3987.132 (Official Build) (64-bit)

Body: Upgrade VS to 16.6 or 16.7-preview1