问:
Double-notched corner in CSS
Is it possible to produce the following shape containing a number with CSS:

I've found tons of examples with a solid background and no border, but those don't apply.

答:
I already did something similar here: https://codepen.io/t_afif/pen/bGooZmq

I will update a few values to get the corners you want:

button {
  --border: 5px;    /* the border width */
  --slant: 0.7em;   /* control the slanted corners */
  --color: #37E8FC; /* the color */

  font-size: 35px;
  padding: 0.4em 1.2em;
  border: none;
  cursor: pointer;
  font-weight: bold;
  color: var(--color);
  background:
     linear-gradient(to bottom right,var(--color)  50%,#0000 50.1%) top left,
     linear-gradient(to top    left ,var(--color)  50%,#0000 50.1%) bottom right;
  background-size: calc(var(--slant) + 1.3*var(--border)) calc(var(--slant) + 1.3*var(--border));
  background-repeat: no-repeat;
  box-shadow:
    0 0 0 200px inset var(--s,#0000),
    0 0 0 var(--border) inset var(--color);
  clip-path:
      polygon(var(--slant) 0, 100% 0, 100% calc(100% - var(--slant)),
      calc(100% - var(--slant)) 100%, 0 100%,0 var(--slant));
  transition: color var(--t,0.3s), background-size 0.3s;
}
button:hover,
button:active{
  background-size: 100% 100%;
  color: #fff;
  --t: 0.2s 0.1s;
}
button:focus-visible {
  outline-offset: calc(-1*var(--border));
  outline: var(--border) solid #000a;
}
button:active {
  --s: #0005;
  transition: none;
}

body {
  display:grid;
  grid-auto-flow:column;
  grid-gap:20px;
  place-content:center;
  margin:0;
  height:100vh;
  background:#eee;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><button>Button</button>
<button style="--color:#f3738a;--border:2px;--slant:.5em">Button</button>
<button style="--color:#69db3a;--slant:40px;--border:8px">Button</button></code>```

Title: Double-notched corner in CSS

Body:
I already did something similar here: https://codepen.io/t_afif/pen/bGooZmq

I will update a few values to get the corners you want:

button {
  --border: 5px;    /* the border width */
  --slant: 0.7em;   /* control the slanted corners */
  --color: #37E8FC; /* the color */

  font-size: 35px;
  padding: 0.4em 1.2em;
  border: none;
  cursor: pointer;
  font-weight: bold;
  color: var(--color);
  background:
     linear-gradient(to bottom right,var(--color)  50%,#0000 50.1%) top left,
     linear-gradient(to top    left ,var(--color)  50%,#0000 50.1%) bottom right;
  background-size: calc(var(--slant) + 1.3*var(--border)) calc(var(--slant) + 1.3*var(--border));
  background-repeat: no-repeat;
  box-shadow:
    0 0 0 200px inset var(--s,#0000),
    0 0 0 var(--border) inset var(--color);
  clip-path:
      polygon(var(--slant) 0, 100% 0, 100% calc(100% - var(--slant)),
      calc(100% - var(--slant)) 100%, 0 100%,0 var(--slant));
  transition: color var(--t,0.3s), background-size 0.3s;
}
button:hover,
button:active{
  background-size: 100% 100%;
  color: #fff;
  --t: 0.2s 0.1s;
}
button:focus-visible {
  outline-offset: calc(-1*var(--border));
  outline: var(--border) solid #000a;
}
button:active {
  --s: #0005;
  transition: none;
}

body {
  display:grid;
  grid-auto-flow:column;
  grid-gap:20px;
  place-content:center;
  margin:0;
  height:100vh;
  background:#eee;
}

<button>Button</button>
<button style="--color:#f3738a;--border:2px;--slant:.5em">Button</button>
<button style="--color:#69db3a;--slant:40px;--border:8px">Button</button>


来源: stackexchange

问:
How to return json array in return res.json in Node?
I'm able to return the array of data using this:

```<code> router.get('/api/person', async (req, res) => {
    const personData = await Person.find()
    return res.json(personData)
  })
</code>```

But I'm not able to do so using this second method

```<code>router.get('/api/person', async (req, res) => {
    const personData = await Person.find()
    return res.json({personInfo:[{
      id: personData._id,
      name: personData.personName,
      address: personData.personAddress
    }]})
  })
</code>```

How should I return an array of data using the second method? Thanks

答:
Your question is not related to mongoose. What you are looking for is a javascript concept called map.

Your mongo query is returning the data that it has stored in it's database, there's nothing wrong in that. What you want to do after that is transform the incoming array into a different structure before sending it off.

With the help of map we can iterate over the personData array and create a new array with only the three elements that you require.

Your code should look like this (Definitely suggest you to read more about the map function so that you understand it well):

```<code>router.get("/api/person", async (req, res) => {
  const personData = await Person.find();

  const personInfo = personData.map((person) => {
    return {
      id: person._id,
      name: person.personName,
      address: person.personAddress,
    };
  });

  return res.json({ personInfo });
});
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm able to return the array of data using this:

 router.get('/api/person', async (req, res) => {
    const personData = await Person.find()
    return res.json(personData)
  })

But I'm not able to do so using this second method

router.get('/api/person', async (req, res) => {
    const personData = await Person.find()
    return res.json({personInfo:[{
      id: personData._id,
      name: personData.personName,
      address: personData.personAddress
    }]})
  })

How should I return an array of data using the second method? Thanks

Body:
Your question is not related to mongoose. What you are looking for is a javascript concept called map.

Your mongo query is returning the data that it has stored in it's database, there's nothing wrong in that. What you want to do after that is transform the incoming array into a different structure before sending it off.

With the help of map we can iterate over the personData array and create a new array with only the three elements that you require.

Your code should look like this (Definitely suggest you to read more about the map function so that you understand it well):

router.get("/api/person", async (req, res) => {
  const personData = await Person.find();

  const personInfo = personData.map((person) => {
    return {
      id: person._id,
      name: person.personName,
      address: person.personAddress,
    };
  });

  return res.json({ personInfo });
});


问:
ThreadMXBean.dumpAllThreads() maxDepth
I'm trying to write some Thread Management utility, and reading up on ThreadMXBean.

http://download.oracle.com/javase/6/docs/api/java/lang/management/ThreadMXBean.html#dumpAllThreads(boolean, boolean)

According to the doc, getThreadInfo(long[] ids, int maxDepth) "does not obtain the locked monitors and locked synchronizers of the threads", however, those methods that allow you to specify true to obtain lock/monitor information do not seem to enable you to specify maxDepth.

Is there anything I can do to specify both whether or not to obtain monitor/lock info as well as stack depth?

Thanks in advance!

答:
You can copy the toString() from ThreadInfo, but remove the stack depth limitation to give you this :

```<code>    public String dump(ThreadInfo info) {

        StringBuilder sb = new StringBuilder("\"" + info.getThreadName() + "\""
                + " Id=" + info.getThreadId() + " " + info.getThreadState());
        if (info.getLockName() != null) {
            sb.append(" on " + info.getLockName());
        }
        if (info.getLockOwnerName() != null) {
            sb.append(" owned by \"" + info.getLockOwnerName() + "\" Id="
                    + info.getLockOwnerId());
        }
        if (info.isSuspended()) {
            sb.append(" (suspended)");
        }
        if (info.isInNative()) {
            sb.append(" (in native)");
        }
        sb.append('\n');
        int i = 0;
        for (; i < info.getStackTrace().length; i++) {
            StackTraceElement ste = info.getStackTrace()[i];
            sb.append("\tat " + ste.toString());
            sb.append('\n');
            if (i == 0 && info.getLockInfo() != null) {
                Thread.State ts = info.getThreadState();
                switch (ts) {
                case BLOCKED:
                    sb.append("\t-  blocked on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case TIMED_WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                default:
                }
            }

            for (MonitorInfo mi : info.getLockedMonitors()) {
                if (mi.getLockedStackDepth() == i) {
                    sb.append("\t-  locked " + mi);
                    sb.append('\n');
                }
            }
        }
        if (i < info.getStackTrace().length) {
            sb.append("\t...");
            sb.append('\n');
        }

        LockInfo[] locks = info.getLockedSynchronizers();
        if (locks.length > 0) {
            sb.append("\n\tNumber of locked synchronizers = " + locks.length);
            sb.append('\n');
            for (LockInfo li : locks) {
                sb.append("\t- " + li);
                sb.append('\n');
            }
        }
        sb.append('\n');
        return sb.toString();
    }
</code>```

Then call this method for each ThreadInfo returned from ThreadMxBean.dumpAllThreads()

Here is a gist with a utility class that has this method along with some sonarlint cleanup: https://gist.github.com/nddipiazza/13edf47fae104c34dd0331704bcf04e9

ContentLicense: CC BY-SA 3.0

Title: ThreadMXBean.dumpAllThreads() maxDepth

Body:
You can copy the toString() from ThreadInfo, but remove the stack depth limitation to give you this :

    public String dump(ThreadInfo info) {

        StringBuilder sb = new StringBuilder("\"" + info.getThreadName() + "\""
                + " Id=" + info.getThreadId() + " " + info.getThreadState());
        if (info.getLockName() != null) {
            sb.append(" on " + info.getLockName());
        }
        if (info.getLockOwnerName() != null) {
            sb.append(" owned by \"" + info.getLockOwnerName() + "\" Id="
                    + info.getLockOwnerId());
        }
        if (info.isSuspended()) {
            sb.append(" (suspended)");
        }
        if (info.isInNative()) {
            sb.append(" (in native)");
        }
        sb.append('\n');
        int i = 0;
        for (; i < info.getStackTrace().length; i++) {
            StackTraceElement ste = info.getStackTrace()[i];
            sb.append("\tat " + ste.toString());
            sb.append('\n');
            if (i == 0 && info.getLockInfo() != null) {
                Thread.State ts = info.getThreadState();
                switch (ts) {
                case BLOCKED:
                    sb.append("\t-  blocked on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                case TIMED_WAITING:
                    sb.append("\t-  waiting on " + info.getLockInfo());
                    sb.append('\n');
                    break;
                default:
                }
            }

            for (MonitorInfo mi : info.getLockedMonitors()) {
                if (mi.getLockedStackDepth() == i) {
                    sb.append("\t-  locked " + mi);
                    sb.append('\n');
                }
            }
        }
        if (i < info.getStackTrace().length) {
            sb.append("\t...");
            sb.append('\n');
        }

        LockInfo[] locks = info.getLockedSynchronizers();
        if (locks.length > 0) {
            sb.append("\n\tNumber of locked synchronizers = " + locks.length);
            sb.append('\n');
            for (LockInfo li : locks) {
                sb.append("\t- " + li);
                sb.append('\n');
            }
        }
        sb.append('\n');
        return sb.toString();
    }

Then call this method for each ThreadInfo returned from ThreadMxBean.dumpAllThreads()

Here is a gist with a utility class that has this method along with some sonarlint cleanup: https://gist.github.com/nddipiazza/13edf47fae104c34dd0331704bcf04e9


问:
How to find MySQL error log file on Windows?
I just downloaded MySQL on Windows, and I am trying to run MySQl from the command line. When I try to login as root, the server simply freezes and does nothing. If I enter the incorrect password, it denies me access, but when I enter the correct password, it's hanging.

enter image description here

I am trying to figure out where to view the MySQL log/error files, but cannot find them on my system.

答:
They can be found in the hidden folder

```<code>C:\ProgramData\MySQL\MySQL Server 8.0\Data
</code>```

But you should run rhe MySQL installer and reconfigure the server and follow the steps, where you enter the password

Body:
They can be found in the hidden folder

C:\ProgramData\MySQL\MySQL Server 8.0\Data

But you should run rhe MySQL installer and reconfigure the server and follow the steps, where you enter the password


问:
laravel collection restructure to nested
I have query result wrapped to larave collection:

```<code>[
    [
        'group_id' => 1,
        'value_id' => 1
    ],
    [
        'group_id' => 1,
        'value_id' => 2
    ],
    [
        'group_id' => 2,
        'value_id' => 3
    ]
];
</code>```

this collection.
How can i make this

```<code>[
    [
        'group_id' => 1,
        'values' => [
            [
                'value_id' => 1
            ],
            [
                'value_id' => 2
            ]
        ]
    ],
    [
        'group_id' => 2,
        'values' => [
            [
                'value_id' => 3
            ]
        ]
    ]
];
</code>```

Preferably with laravel collection methods.I will be very grateful to you.

答:
Use groupBy, map, forget... There are many ways that you can do, just by reading the documentation.

```<code>$data = [
    [
        'group_id' => 1,
        'value_id' => 1
    ],
    [
        'group_id' => 1,
        'value_id' => 2
    ],
    [
        'group_id' => 2,
        'value_id' => 3
    ]
];

$data = collect($data)
    ->groupBy('group_id')
    ->map(function($item, $key){
        return [
            'group_id' => $key,
            'values' => collect($item)->map(function($item){
                return collect($item)->forget('group_id')->all();
            })->toArray()
        ];
    })
    ->toArray();

dd($data);
</code>```

Output :

```<code>array:2 [
  1 => array:2 [
    "group_id" => 1
    "values" => array:2 [
      0 => array:1 [
        "value_id" => 1
      ]
      1 => array:1 [
        "value_id" => 2
      ]
    ]
  ]
  2 => array:2 [
    "group_id" => 2
    "values" => array:1 [
      0 => array:1 [
        "value_id" => 3
      ]
    ]
  ]
]
</code>```

Body:
I have query result wrapped to larave collection:

[
    [
        'group_id' => 1,
        'value_id' => 1
    ],
    [
        'group_id' => 1,
        'value_id' => 2
    ],
    [
        'group_id' => 2,
        'value_id' => 3
    ]
];

this collection.
How can i make this

[
    [
        'group_id' => 1,
        'values' => [
            [
                'value_id' => 1
            ],
            [
                'value_id' => 2
            ]
        ]
    ],
    [
        'group_id' => 2,
        'values' => [
            [
                'value_id' => 3
            ]
        ]
    ]
];

Preferably with laravel collection methods.I will be very grateful to you.

Body:
Use groupBy, map, forget... There are many ways that you can do, just by reading the documentation.

$data = [
    [
        'group_id' => 1,
        'value_id' => 1
    ],
    [
        'group_id' => 1,
        'value_id' => 2
    ],
    [
        'group_id' => 2,
        'value_id' => 3
    ]
];

$data = collect($data)
    ->groupBy('group_id')
    ->map(function($item, $key){
        return [
            'group_id' => $key,
            'values' => collect($item)->map(function($item){
                return collect($item)->forget('group_id')->all();
            })->toArray()
        ];
    })
    ->toArray();

dd($data);

Output :

array:2 [
  1 => array:2 [
    "group_id" => 1
    "values" => array:2 [
      0 => array:1 [
        "value_id" => 1
      ]
      1 => array:1 [
        "value_id" => 2
      ]
    ]
  ]
  2 => array:2 [
    "group_id" => 2
    "values" => array:1 [
      0 => array:1 [
        "value_id" => 3
      ]
    ]
  ]
]


问:
Set Tooltip over line Chartjs
I wanna show tooltips over the line not only on data points.
I also tried the chartjs-plugin-crosshair but it doesn't work in V3 of chartjs.

答:
You can write a custom implementation for V3 for it:

// Options for the indicators
const indicatorOptions = {
  radius: 4,
  borderWidth: 1,
  borderColor: 'red',
  backgroundColor: 'transparent'
};

// Override getLabelAndValue to return the interpolated value
const getLabelAndValue = Chart.controllers.line.prototype.getLabelAndValue;
Chart.controllers.line.prototype.getLabelAndValue = function(index) {
  if (index === -1) {
    const meta = this.getMeta();
    const pt = meta._pt;
    const vScale = meta.vScale;
    return {
      label: 'interpolated',
      value: vScale.getValueForPixel(pt.y)
    };
  }
  return getLabelAndValue.call(this, index);
}

// The interaction mode
Chart.Interaction.modes.interpolate = function(chart, e, option) {
  const x = e.x;
  const items = [];
  const metas = chart.getSortedVisibleDatasetMetas();
  for (let i = 0; i < metas.length; i++) {
    const meta = metas[i];
    const pt = meta.dataset.interpolate({
      x
    }, "x");
    if (pt) {
      const element = new Chart.elements.PointElement({ ...pt,
        options: { ...indicatorOptions
        }
      });
      meta._pt = element;
      items.push({
        element,
        index: -1,
        datasetIndex: meta.index
      });
    } else {
      meta._pt = null;
    }
  }
  return items;
};

// Plugin to draw the indicators
Chart.register({
  id: 'indicators',
  afterDraw(chart) {
    const metas = chart.getSortedVisibleDatasetMetas();
    for (let i = 0; i < metas.length; i++) {
      const meta = metas[i];
      if (meta._pt) {
        meta._pt.draw(chart.ctx);
      }
    }
  },
  afterEvent(chart, args) {
    if (args.event.type === 'mouseout') {
      const metas = chart.getSortedVisibleDatasetMetas();
      for (let i = 0; i < metas.length; i++) {
        metas[i]._pt = null;
      }
      args.changed = true;
    }
  }
})

var ctx = document.getElementById("myChart").getContext("2d");
var chart = new Chart(ctx, {
  type: "line",
  data: {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
        fill: true,
        label: "My First dataset",
        backgroundColor: "rgba(132, 0, 0, 1)",
        borderColor: "rgb(255, 99, 132)",
        data: [0, 10, 5, 2, 20, 30, 45]
      },
      {
        data: [30, 40, 50],
        label: 'My Second Dataset',
        fill: true,
        backgroundColor: "lightgreen",
        borderColor: "green"
      }
    ]
  },
  options: {
    interaction: {
      mode: "interpolate",
      intersect: false,
      axis: "x"
    },
    plugins: {
      tooltip: {
        displayColors: false,
      }
    }
  },
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
<h1>Interpolating line values</h1>
<div class="myChartDiv">
  <canvas id="myChart" width="600" height="400"></canvas>
</div></code>```

Title: Set Tooltip over line Chartjs

Body:
You can write a custom implementation for V3 for it:

// Options for the indicators
const indicatorOptions = {
  radius: 4,
  borderWidth: 1,
  borderColor: 'red',
  backgroundColor: 'transparent'
};

// Override getLabelAndValue to return the interpolated value
const getLabelAndValue = Chart.controllers.line.prototype.getLabelAndValue;
Chart.controllers.line.prototype.getLabelAndValue = function(index) {
  if (index === -1) {
    const meta = this.getMeta();
    const pt = meta._pt;
    const vScale = meta.vScale;
    return {
      label: 'interpolated',
      value: vScale.getValueForPixel(pt.y)
    };
  }
  return getLabelAndValue.call(this, index);
}

// The interaction mode
Chart.Interaction.modes.interpolate = function(chart, e, option) {
  const x = e.x;
  const items = [];
  const metas = chart.getSortedVisibleDatasetMetas();
  for (let i = 0; i < metas.length; i++) {
    const meta = metas[i];
    const pt = meta.dataset.interpolate({
      x
    }, "x");
    if (pt) {
      const element = new Chart.elements.PointElement({ ...pt,
        options: { ...indicatorOptions
        }
      });
      meta._pt = element;
      items.push({
        element,
        index: -1,
        datasetIndex: meta.index
      });
    } else {
      meta._pt = null;
    }
  }
  return items;
};

// Plugin to draw the indicators
Chart.register({
  id: 'indicators',
  afterDraw(chart) {
    const metas = chart.getSortedVisibleDatasetMetas();
    for (let i = 0; i < metas.length; i++) {
      const meta = metas[i];
      if (meta._pt) {
        meta._pt.draw(chart.ctx);
      }
    }
  },
  afterEvent(chart, args) {
    if (args.event.type === 'mouseout') {
      const metas = chart.getSortedVisibleDatasetMetas();
      for (let i = 0; i < metas.length; i++) {
        metas[i]._pt = null;
      }
      args.changed = true;
    }
  }
})

var ctx = document.getElementById("myChart").getContext("2d");
var chart = new Chart(ctx, {
  type: "line",
  data: {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
        fill: true,
        label: "My First dataset",
        backgroundColor: "rgba(132, 0, 0, 1)",
        borderColor: "rgb(255, 99, 132)",
        data: [0, 10, 5, 2, 20, 30, 45]
      },
      {
        data: [30, 40, 50],
        label: 'My Second Dataset',
        fill: true,
        backgroundColor: "lightgreen",
        borderColor: "green"
      }
    ]
  },
  options: {
    interaction: {
      mode: "interpolate",
      intersect: false,
      axis: "x"
    },
    plugins: {
      tooltip: {
        displayColors: false,
      }
    }
  },
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.js"></script>
<h1>Interpolating line values</h1>
<div class="myChartDiv">
  <canvas id="myChart" width="600" height="400"></canvas>
</div>


问:
iPhone - Problem with NSDate to get time interval according to current time zone
I am using NSDate to get the NSTimeInterval according to current time zone.
But I'm getting information related to UTC.
I'm using methods like "dateWithTimeIntervalSinceNow" and "dateWithTimeIntervalSince1970"
How can I get time interval as per my time zone?</p>

答:
If both are NSDates then you could do :</p>

```<code>//calculate the time difference in seconds, that is absolute and does not depend in time zones :)
double timeDiffInSecs = [date1 timeIntervalSince1970] - [date2 timeIntervalSince1970];
</code>```

Body:
If both are NSDates then you could do :

//calculate the time difference in seconds, that is absolute and does not depend in time zones :)
double timeDiffInSecs = [date1 timeIntervalSince1970] - [date2 timeIntervalSince1970];


问:
Axios sending HTTPS XHR to port 80 on Chrome
An API request using Axios from our Vue.js frontend is failing, but only in Chrome.

The network inspector in Chrome / Safari / Firefox shows that Chrome is making the XHR request to port 80, despite the frontend and backend all being HTTPS. Safari and Firefox use 443 as expected.

This wasn’t a problem before. Does anyone know why Axios or Chrome might have started doing this?

Background

This problem appears to have started recently, and we have not updated any low-level frontend code in weeks.

The reported error itself is a 504 returned by Cloudflare, which means our origin server is refusing the request, which makes sense given that it’s on port 80 and we’re expecting 443.

We don’t actually specify the port anywhere in our code. I assumed it was inferred from the protocol unless otherwise specified. It looks to me like Axios is doing this itself or via the different adapters in each browser, but I can’t read the compiled JS very well. Chrome and other browsers seem to correctly switch to port 80 when doing local development without TLS.

答:
This is not the actual problem here.

It turns out that when exporting a .har file from Chrome (a saved copy of all the network requests recorded by a web inspector session), it loses or mangles the port data.

Chrome is making the HTTPS requests to 443 after all.


问:
Laravel 8, Model factory class not found
so when using the new model factories class introduced in laravel 8.x, ive this weird issue saying that laravel cannot find the factory that corresponds to the model. i get this error

```<code>PHP Error:  Class 'Database/Factories/BusinessUserFactory' not found in .....

</code>```

tho ive followed the laravel docs, ive no idea whats going on

Here is the BusinessUser class

```<code><?php

namespace App;

use Database\Factories\BusinessUserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class BusinessUser extends Model
{
    use HasFactory;
}

</code>```

and the factory

```<code><?php

namespace Database\Factories;

use App\BusinessUser;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class BusinessUserFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = BusinessUser::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => "dsfsf"
        ];
    }
}

</code>```

any ideas or leads is greatly appreciated.

答:
It seems like a laravel core issue ! it was caused by the modelName() method located in Illuminate\Database\Eloquent\Factories\Factory.php

Issue was fixed 10 days ago by laravel maintainers in this commit
Fix commit and this release 8.82.0

You can fix the issue by upgrading your laravel version to 8.82.0

Hope this saves you some time. cheers !

Body:
so when using the new model factories class introduced in laravel 8.x, ive this weird issue saying that laravel cannot find the factory that corresponds to the model. i get this error

PHP Error:  Class 'Database/Factories/BusinessUserFactory' not found in .....

tho ive followed the laravel docs, ive no idea whats going on

Here is the BusinessUser class

<?php

namespace App;

use Database\Factories\BusinessUserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class BusinessUser extends Model
{
    use HasFactory;
}

and the factory

<?php

namespace Database\Factories;

use App\BusinessUser;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;

class BusinessUserFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = BusinessUser::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => "dsfsf"
        ];
    }
}

any ideas or leads is greatly appreciated.


问:
Why can't I detect start condition when to bitbang-read/sniff I2C port? stm32
I am trying to bitbang-read or rather sniff an I2C port. I have successful I2C communication between a master I2C device and a Nucleo stm32F401 board. Nucleo slave sending using DMA. Then I am using 2 pins from the same Nucleo to try to sniff the communication. Both of the pins are configured as inuputs with pull-ups.

I read the pins' value like this:

```<code>while (1) {

    uint8_t CLK_val = HAL_GPIO_ReadPin(GPIOB, 1);
    uint8_t SDA_val = HAL_GPIO_ReadPin(GPIOB, 2);

//And then I try to detect start condition like this:

    if (CLK_val == GPIO_PIN_RESET && SDA_val == GPIO_PIN_RESET){
        //Some code
    }

//More code

};
</code>```

If I manually pull the pins down, touching both of them with a cable connected to ground, the condition is met. But the I2C transaction doesn't trigger the condition even though the transaction is being successful and thus the pins must have been pulled down during the transaction.

Why would the condition not be met during the I2C transaction?

答:
AN I2C start condition is a falling edge of data while clock remains high.  To detect it from GPIO you need to do something like:</p>
```<code>CLK_val_before = HAL_GPIO_ReadPin(GPIOB, 1);
SDA_val_before = HAL_GPIO_ReadPin(GPIOB, 2);
CLK_val_after = HAL_GPIO_ReadPin(GPIOB, 1);
SDA_val_after = HAL_GPIO_ReadPin(GPIOB, 2);

if ((CLK_val_before == GPIO_PIN_SET)
    && (SDA_val_before == GPIO_PIN_SET)
    && (CLK_val_after == GPIO_PIN_SET)
    && (SDA_val_after == GPIO_PIN_RESET))
{
    // Some code
}
</code>```

Body:
I am trying to bitbang-read or rather sniff an I2C port. I have successful I2C communication between a master I2C device and a Nucleo stm32F401 board. Nucleo slave sending using DMA. Then I am using 2 pins from the same Nucleo to try to sniff the communication. Both of the pins are configured as inuputs with pull-ups.

I read the pins' value like this:

while (1) {

    uint8_t CLK_val = HAL_GPIO_ReadPin(GPIOB, 1);
    uint8_t SDA_val = HAL_GPIO_ReadPin(GPIOB, 2);

//And then I try to detect start condition like this:

    if (CLK_val == GPIO_PIN_RESET && SDA_val == GPIO_PIN_RESET){
        //Some code
    }

//More code

};

If I manually pull the pins down, touching both of them with a cable connected to ground, the condition is met. But the I2C transaction doesn't trigger the condition even though the transaction is being successful and thus the pins must have been pulled down during the transaction.

Why would the condition not be met during the I2C transaction?

Body:
AN I2C start condition is a falling edge of data while clock remains high.  To detect it from GPIO you need to do something like:

CLK_val_before = HAL_GPIO_ReadPin(GPIOB, 1);
SDA_val_before = HAL_GPIO_ReadPin(GPIOB, 2);
CLK_val_after = HAL_GPIO_ReadPin(GPIOB, 1);
SDA_val_after = HAL_GPIO_ReadPin(GPIOB, 2);

if ((CLK_val_before == GPIO_PIN_SET)
    && (SDA_val_before == GPIO_PIN_SET)
    && (CLK_val_after == GPIO_PIN_SET)
    && (SDA_val_after == GPIO_PIN_RESET))
{
    // Some code
}


问:
updating the database with single migration?
I have a table that has "projects" that have this field workspace which takes an array of strings. So I have converted this to store a single character

```<code> create table("projects") do
  add(:name, :string, null: false)
  add(:title, :string, null: false)
  add(:workspaces, {:array, :string})

  timestamps()
end
</code>```

I have written this migration to store a single string

```<code>alter table(:projects) do
      modify(:workspace, :string)
</code>```

I want to run this migration but also I want to update all the data which is stored in the database. I need to update all the workspace data to store a single string.

Suppose if workspace has this value {value1, value2}. It will look for value1 and if that is found it will store the value1 otherwise it will store value2

This is how {value1, value2} it is stored in the database table. So when we load it in elixir it looks something like this ["value1", "value2"]

What can I do here?

答:
It looks like you're trying to do a schema-less database within your relational database. This is going to get hard pretty quickly. You might be better served using a schemaless database like couch or mongo.

However if you're using postgres, the jsonb or json column types would better serve this use case IMO. The data is a tad bit harder to query as the postgres operators are interesting, but once you wrap your head around it it's not too bad and the performance with proper indexes will be on par with schemaless. Also you get the added benefit of not having to write serializing/deserializing to your database layer.

Body:
I have a table that has "projects" that have this field workspace which takes an array of strings. So I have converted this to store a single character

 create table("projects") do
  add(:name, :string, null: false)
  add(:title, :string, null: false)
  add(:workspaces, {:array, :string})

  timestamps()
end

I have written this migration to store a single string

alter table(:projects) do
      modify(:workspace, :string)

I want to run this migration but also I want to update all the data which is stored in the database. I need to update all the workspace data to store a single string.

Suppose if workspace has this value {value1, value2}. It will look for value1 and if that is found it will store the value1 otherwise it will store value2

This is how {value1, value2} it is stored in the database table. So when we load it in elixir it looks something like this ["value1", "value2"]

What can I do here?


问:
Switching To Routers in FastApi did not go well. response_model List[] pydantic field type error
I have a Python 3.8 app that uses FastApi. There were getting to be too many routes in main.py so I embraced switching from FastApi application object to the router and putting a route per db table in its own file. So far it has not worked due to interpretation of the response_model decorator.

The switch has caused my modified code to have trouble with the response_model decorators Post. The biggest difference is I am using the router decorator as opposed to the application decorator in main.

The specific error I am getting is:

```<code> File "/Users/markwardell/PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/fastapi/utils.py", line 67, in create_response_field
    raise fastapi.exceptions.FastAPIError(
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that typing.List[models.Post] is a valid pydantic field type
</code>```

The code that is causing this error is here in post.py where I broke it out from main.py

post.py

from fastapi import HTTPException,  APIRouter
from sqlalchemy.orm import Session
from typing import List
from fastapi.params import Depends

```<code>import models
from database import get_db

router: APIRouter = APIRouter()

@router.get("/postss", response_model=List[models.Post])
def get_post(db: Session = Depends(get_db)):
    # cursor.execute("""SELECT * FROM posts""")
    # posts = cursor.fetchall()
    # print(posts)

    try:
        posts = db.query(models.Post).all()
    except Exception as ex:
        msg = f"Unexpected {ex=}, {type(ex)=}"
        raise HTTPException(status_code=500, detail=msg)
    return posts
</code>```

The original code which works:

main.py

from fastapi import FastAPI, Response, HTTPException
from fastapi.params import Depends
from starlette import status
import user
import post

```<code>import models
import schemas
from database import engine, get_db
from sqlalchemy.orm import Session

models.Base.metadata.create_all(bind=engine)

app = FastAPI()
app.include_router(user.router)
app.include_router(post.router)

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)

@app.get("/")
async def root():
    return {"message": "Welcome To My Api!"}

@app.get("/posts", response_model=List[schemas.Post])
def get_posts(db: Session = Depends(get_db)):
    # cursor.execute("""SELECT * FROM posts""")
    # posts = cursor.fetchall()
    # print(posts)

    try:
        posts = db.query(models.Post).all()
    except Exception as ex:
        msg = f"Unexpected {ex=}, {type(ex)=}"
        raise HTTPException(status_code=500, detail=msg)
    return posts
</code>```

here is the definition of the response_model(s)

schema.py

```<code>from datetime import datetime

from pydantic import BaseModel, EmailStr

class PostBase(BaseModel):
    title: str
    content: str
    published: bool = True

class PostCreate(BaseModel):
    pass

class Post(PostBase):
    id: int
    created_at: datetime

    class Config:
        orm_mode = True
        arbitrary_types_allowed = True

class UserCreate(BaseModel):
    email: EmailStr
    password: str

class UserOut(BaseModel):
    id: int
    email: EmailStr
    created_at: datetime

    class Config:
        orm_mode = True
</code>```

答: You have the wrong type of class in your response_model definition; the reference should point to your schema (which inherits from pydantic's BaseModel) - your response_model points to your SQLAlchemy model (i.e. schema vs model in your module name).

Body:
I have a Python 3.8 app that uses FastApi. There were getting to be too many routes in main.py so I embraced switching from FastApi application object to the router and putting a route per db table in its own file. So far it has not worked due to interpretation of the response_model decorator.

The switch has caused my modified code to have trouble with the response_model decorators Post. The biggest difference is I am using the router decorator as opposed to the application decorator in main.

The specific error I am getting is:

 File "/Users/markwardell/PycharmProjects/pythonProject/venv/lib/python3.8/site-packages/fastapi/utils.py", line 67, in create_response_field
    raise fastapi.exceptions.FastAPIError(
fastapi.exceptions.FastAPIError: Invalid args for response field! Hint: check that typing.List[models.Post] is a valid pydantic field type

The code that is causing this error is here in post.py where I broke it out from main.py

post.py

from fastapi import HTTPException,  APIRouter
from sqlalchemy.orm import Session
from typing import List
from fastapi.params import Depends

import models
from database import get_db

router: APIRouter = APIRouter()

@router.get("/postss", response_model=List[models.Post])
def get_post(db: Session = Depends(get_db)):
    # cursor.execute("""SELECT * FROM posts""")
    # posts = cursor.fetchall()
    # print(posts)

    try:
        posts = db.query(models.Post).all()
    except Exception as ex:
        msg = f"Unexpected {ex=}, {type(ex)=}"
        raise HTTPException(status_code=500, detail=msg)
    return posts

The original code which works:

main.py

from fastapi import FastAPI, Response, HTTPException
from fastapi.params import Depends
from starlette import status
import user
import post

import models
import schemas
from database import engine, get_db
from sqlalchemy.orm import Session

models.Base.metadata.create_all(bind=engine)

app = FastAPI()
app.include_router(user.router)
app.include_router(post.router)

if __name__ == "__main__":
    uvicorn.run(app, host="127.0.0.1", port=8000)

@app.get("/")
async def root():
    return {"message": "Welcome To My Api!"}

@app.get("/posts", response_model=List[schemas.Post])
def get_posts(db: Session = Depends(get_db)):
    # cursor.execute("""SELECT * FROM posts""")
    # posts = cursor.fetchall()
    # print(posts)

    try:
        posts = db.query(models.Post).all()
    except Exception as ex:
        msg = f"Unexpected {ex=}, {type(ex)=}"
        raise HTTPException(status_code=500, detail=msg)
    return posts

here is the definition of the response_model(s)

schema.py

from datetime import datetime

from pydantic import BaseModel, EmailStr

class PostBase(BaseModel):
    title: str
    content: str
    published: bool = True

class PostCreate(BaseModel):
    pass

class Post(PostBase):
    id: int
    created_at: datetime

    class Config:
        orm_mode = True
        arbitrary_types_allowed = True

class UserCreate(BaseModel):
    email: EmailStr
    password: str

class UserOut(BaseModel):
    id: int
    email: EmailStr
    created_at: datetime

    class Config:
        orm_mode = True


问:
how to repeat the height for grid-auto-rows
I am trying to show only the first two rows of a CSS GRID.

The width of the container is unknown therefore it should be responsive.

Also the content of each box is unknown.

My current hacky solution is to define the following two rules:

use an automatic height for the first two rows

set the height of the next 277 rows to 0 height

grid-auto-rows: auto auto 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;

I tried repeat() like this: grid-auto-rows: auto auto repeat(277, 0px) but unfortunately it didn't set the height to 0.

Is there any clean way to repeat height 0?

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-auto-rows: auto auto 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><h1>Colors</h1>
<ul>
  <li>Android green</li>
  <li>Antique brass</li>
  <li>Antique bronze</li>
  <li>Antique fuchsia</li>
  <li>Antique ruby</li>
  <li>Antique white</li>
  <li>Ao (English)</li>
  <li>Apple green</li>
  <li>Apricot</li>
  <li>Aqua</li>
  <li>Aquamarine</li>
  <li>Arctic lime</li>
  <li>Army green</li>
  <li>Artichoke</li>
  <li>Arylide yellow</li>
  <li>Ash gray</li>
  <li>Asparagus</li>
  <li>Astronaut</li>
  <li>Atomic tangerine</li>
  <li>Auburn</li>
  <li>Aureolin</li>
  <li>Avocado</li>
  <li>Azure</li>
  <li>Azure (X11/web color)</li>
  <li>Baby blue</li>
  <li>Baby blue eyes</li>
  <li>Baby pink</li>
  <li>Baby powder</li>
  <li>Baker-Miller pink</li>
  <li>Banana Mania</li>
  <li>Barbie Pink</li>
  <li>Barn red</li>
  <li>Battleship grey</li>
  <li>Beau blue</li>
  <li>Beaver</li>
  <li>Beige</li>
  <li>B'dazzled blue</li>
  <li>Big dip o’ruby</li>
  <li>Bisque</li>
  <li>Bistre</li>
  <li>Bistre brown</li>
  <li>Bitter lemon</li>
  <li>Bitter lime</li>
  <li>Bittersweet</li>
  <li>Bittersweet shimmer</li>
  <li>Black</li>
  <li>Black bean</li>
  <li>Black chocolate</li>
  <li>Black coffee</li>
  <li>Black coral</li>
  <li>Black olive</li>
  <li>Black Shadows</li>
  <li>Blanched almond</li>
  <li>Blast-off bronze</li>
  <li>Bleu de France</li>
  <li>Blizzard blue</li>
  <li>Blond</li>
  <li>Blood red</li>
  <li>Blue</li>
  <li>Blue (Crayola)</li>
  <li>Blue (Munsell)</li>
  <li>Blue (NCS)</li>
  <li>Blue (Pantone)</li>
  <li>Blue (pigment)</li>
  <li>Blue (RYB)</li>
  <li>Blue bell</li>
  <li>Blue-gray</li>
  <li>Blue-green</li>
  <li>Blue-green (color wheel)</li>
  <li>Blue jeans</li>
  <li>Blue sapphire</li>
  <li>Blue-violet</li>
  <li>Blue-violet (Crayola)</li>
  <li>Blue-violet (color wheel)</li>
  <li>Blue yonder</li>
  <li>Bluetiful</li>
  <li>Blush</li>
  <li>Bole</li>
  <li>Bone</li>
  <li>Bottle green</li>
  <li>Brandy</li>
  <li>Brick red</li>
  <li>Bright green</li>
  <li>Bright lilac</li>
  <li>Bright maroon</li>
  <li>Bright navy blue</li>
  <li>Bright yellow (Crayola)</li>
  <li>Brilliant rose</li>
</ul></code>```

答:
Define a template for the two rows and then use grid-auto-rows with 0

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-template-rows: auto auto;
  grid-auto-rows: 0;
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><h1>Colors</h1>
<ul>
  <li>Android green</li>
  <li>Antique brass</li>
  <li>Antique bronze</li>
  <li>Antique fuchsia</li>
  <li>Antique ruby</li>
  <li>Antique white</li>
  <li>Ao (English)</li>
  <li>Apple green</li>
  <li>Apricot</li>
  <li>Aqua</li>
  <li>Aquamarine</li>
  <li>Arctic lime</li>
  <li>Army green</li>
  <li>Artichoke</li>
  <li>Arylide yellow</li>
  <li>Ash gray</li>
  <li>Asparagus</li>
  <li>Astronaut</li>
  <li>Atomic tangerine</li>
  <li>Auburn</li>
  <li>Aureolin</li>
  <li>Avocado</li>
  <li>Azure</li>
  <li>Azure (X11/web color)</li>
  <li>Baby blue</li>
  <li>Baby blue eyes</li>
  <li>Baby pink</li>
  <li>Baby powder</li>
  <li>Baker-Miller pink</li>
  <li>Banana Mania</li>
  <li>Barbie Pink</li>
  <li>Barn red</li>
  <li>Battleship grey</li>
  <li>Beau blue</li>
  <li>Beaver</li>
  <li>Beige</li>
  <li>B'dazzled blue</li>
  <li>Big dip o’ruby</li>
  <li>Bisque</li>
  <li>Bistre</li>
  <li>Bistre brown</li>
  <li>Bitter lemon</li>
  <li>Bitter lime</li>
  <li>Bittersweet</li>
  <li>Bittersweet shimmer</li>
  <li>Black</li>
  <li>Black bean</li>
  <li>Black chocolate</li>
  <li>Black coffee</li>
  <li>Black coral</li>
  <li>Black olive</li>
  <li>Black Shadows</li>
  <li>Blanched almond</li>
  <li>Blast-off bronze</li>
  <li>Bleu de France</li>
  <li>Blizzard blue</li>
  <li>Blond</li>
  <li>Blood red</li>
  <li>Blue</li>
  <li>Blue (Crayola)</li>
  <li>Blue (Munsell)</li>
  <li>Blue (NCS)</li>
  <li>Blue (Pantone)</li>
  <li>Blue (pigment)</li>
  <li>Blue (RYB)</li>
  <li>Blue bell</li>
  <li>Blue-gray</li>
  <li>Blue-green</li>
  <li>Blue-green (color wheel)</li>
  <li>Blue jeans</li>
  <li>Blue sapphire</li>
  <li>Blue-violet</li>
  <li>Blue-violet (Crayola)</li>
  <li>Blue-violet (color wheel)</li>
  <li>Blue yonder</li>
  <li>Bluetiful</li>
  <li>Blush</li>
  <li>Bole</li>
  <li>Bone</li>
  <li>Bottle green</li>
  <li>Brandy</li>
  <li>Brick red</li>
  <li>Bright green</li>
  <li>Bright lilac</li>
  <li>Bright maroon</li>
  <li>Bright navy blue</li>
  <li>Bright yellow (Crayola)</li>
  <li>Brilliant rose</li>
</ul></code>```

From the specification:

The grid-auto-columns and grid-auto-rows properties specify the size of tracks not assigned a size by grid-template-rows or grid-template-columns. If multiple track sizes are given, the pattern is repeated as necessary to find the size of the affected tracks.

For the repeat() idea it can only be used with grid-template-rows not grid-auto-rows but you don't have to because the grid-auto-rows was designed for this purpose "define the height of the remaining rows"

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-template-rows: auto auto repeat(300,0);
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><h1>Colors</h1>
<ul>
  <li>Android green</li>
  <li>Antique brass</li>
  <li>Antique bronze</li>
  <li>Antique fuchsia</li>
  <li>Antique ruby</li>
  <li>Antique white</li>
  <li>Ao (English)</li>
  <li>Apple green</li>
  <li>Apricot</li>
  <li>Aqua</li>
  <li>Aquamarine</li>
  <li>Arctic lime</li>
  <li>Army green</li>
  <li>Artichoke</li>
  <li>Arylide yellow</li>
  <li>Ash gray</li>
  <li>Asparagus</li>
  <li>Astronaut</li>
  <li>Atomic tangerine</li>
  <li>Auburn</li>
  <li>Aureolin</li>
  <li>Avocado</li>
  <li>Azure</li>
  <li>Azure (X11/web color)</li>
  <li>Baby blue</li>
  <li>Baby blue eyes</li>
  <li>Baby pink</li>
  <li>Baby powder</li>
  <li>Baker-Miller pink</li>
  <li>Banana Mania</li>
  <li>Barbie Pink</li>
  <li>Barn red</li>
  <li>Battleship grey</li>
  <li>Beau blue</li>
  <li>Beaver</li>
  <li>Beige</li>
  <li>B'dazzled blue</li>
  <li>Big dip o’ruby</li>
  <li>Bisque</li>
  <li>Bistre</li>
  <li>Bistre brown</li>
  <li>Bitter lemon</li>
  <li>Bitter lime</li>
  <li>Bittersweet</li>
  <li>Bittersweet shimmer</li>
  <li>Black</li>
  <li>Black bean</li>
  <li>Black chocolate</li>
  <li>Black coffee</li>
  <li>Black coral</li>
  <li>Black olive</li>
  <li>Black Shadows</li>
  <li>Blanched almond</li>
  <li>Blast-off bronze</li>
  <li>Bleu de France</li>
  <li>Blizzard blue</li>
  <li>Blond</li>
  <li>Blood red</li>
  <li>Blue</li>
  <li>Blue (Crayola)</li>
  <li>Blue (Munsell)</li>
  <li>Blue (NCS)</li>
  <li>Blue (Pantone)</li>
  <li>Blue (pigment)</li>
  <li>Blue (RYB)</li>
  <li>Blue bell</li>
  <li>Blue-gray</li>
  <li>Blue-green</li>
  <li>Blue-green (color wheel)</li>
  <li>Blue jeans</li>
  <li>Blue sapphire</li>
  <li>Blue-violet</li>
  <li>Blue-violet (Crayola)</li>
  <li>Blue-violet (color wheel)</li>
  <li>Blue yonder</li>
  <li>Bluetiful</li>
  <li>Blush</li>
  <li>Bole</li>
  <li>Bone</li>
  <li>Bottle green</li>
  <li>Brandy</li>
  <li>Brick red</li>
  <li>Bright green</li>
  <li>Bright lilac</li>
  <li>Bright maroon</li>
  <li>Bright navy blue</li>
  <li>Bright yellow (Crayola)</li>
  <li>Brilliant rose</li>
</ul></code>```

Body:
I am trying to show only the first two rows of a CSS GRID.

The width of the container is unknown therefore it should be responsive.

Also the content of each box is unknown.

My current hacky solution is to define the following two rules:

use an automatic height for the first two rows

set the height of the next 277 rows to 0 height

grid-auto-rows: auto auto 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;

I tried repeat() like this: grid-auto-rows: auto auto repeat(277, 0px) but unfortunately it didn't set the height to 0.

Is there any clean way to repeat height 0?

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-auto-rows: auto auto 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0;
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}

Colors

Android green

Antique brass

Antique bronze

Antique fuchsia

Antique ruby

Antique white

Ao (English)

Apple green

Apricot

Aqua

Aquamarine

Arctic lime

Army green

Artichoke

Arylide yellow

Ash gray

Asparagus

Astronaut

Atomic tangerine

Auburn

Aureolin

Avocado

Azure

Azure (X11/web color)

Baby blue

Baby blue eyes

Baby pink

Baby powder

Baker-Miller pink

Banana Mania

Barbie Pink

Barn red

Battleship grey

Beau blue

Beaver

Beige

B'dazzled blue

Big dip o’ruby

Bisque

Bistre

Bistre brown

Bitter lemon

Bitter lime

Bittersweet

Bittersweet shimmer

Black

Black bean

Black chocolate

Black coffee

Black coral

Black olive

Black Shadows

Blanched almond

Blast-off bronze

Bleu de France

Blizzard blue

Blond

Blood red

Blue

Blue (Crayola)

Blue (Munsell)

Blue (NCS)

Blue (Pantone)

Blue (pigment)

Blue (RYB)

Blue bell

Blue-gray

Blue-green

Blue-green (color wheel)

Blue jeans

Blue sapphire

Blue-violet

Blue-violet (Crayola)

Blue-violet (color wheel)

Blue yonder

Bluetiful

Blush

Bole

Bone

Bottle green

Brandy

Brick red

Bright green

Bright lilac

Bright maroon

Bright navy blue

Bright yellow (Crayola)

Brilliant rose

Body:
Define a template for the two rows and then use grid-auto-rows with 0

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-template-rows: auto auto;
  grid-auto-rows: 0;
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}

<h1><a href="https://en.wikipedia.org/wiki/List_of_colors:_A%E2%80%93F">Colors</a></h1>
<ul>
  <li>Android green</li>
  <li>Antique brass</li>
  <li>Antique bronze</li>
  <li>Antique fuchsia</li>
  <li>Antique ruby</li>
  <li>Antique white</li>
  <li>Ao (English)</li>
  <li>Apple green</li>
  <li>Apricot</li>
  <li>Aqua</li>
  <li>Aquamarine</li>
  <li>Arctic lime</li>
  <li>Army green</li>
  <li>Artichoke</li>
  <li>Arylide yellow</li>
  <li>Ash gray</li>
  <li>Asparagus</li>
  <li>Astronaut</li>
  <li>Atomic tangerine</li>
  <li>Auburn</li>
  <li>Aureolin</li>
  <li>Avocado</li>
  <li>Azure</li>
  <li>Azure (X11/web color)</li>
  <li>Baby blue</li>
  <li>Baby blue eyes</li>
  <li>Baby pink</li>
  <li>Baby powder</li>
  <li>Baker-Miller pink</li>
  <li>Banana Mania</li>
  <li>Barbie Pink</li>
  <li>Barn red</li>
  <li>Battleship grey</li>
  <li>Beau blue</li>
  <li>Beaver</li>
  <li>Beige</li>
  <li>B'dazzled blue</li>
  <li>Big dip o’ruby</li>
  <li>Bisque</li>
  <li>Bistre</li>
  <li>Bistre brown</li>
  <li>Bitter lemon</li>
  <li>Bitter lime</li>
  <li>Bittersweet</li>
  <li>Bittersweet shimmer</li>
  <li>Black</li>
  <li>Black bean</li>
  <li>Black chocolate</li>
  <li>Black coffee</li>
  <li>Black coral</li>
  <li>Black olive</li>
  <li>Black Shadows</li>
  <li>Blanched almond</li>
  <li>Blast-off bronze</li>
  <li>Bleu de France</li>
  <li>Blizzard blue</li>
  <li>Blond</li>
  <li>Blood red</li>
  <li>Blue</li>
  <li>Blue (Crayola)</li>
  <li>Blue (Munsell)</li>
  <li>Blue (NCS)</li>
  <li>Blue (Pantone)</li>
  <li>Blue (pigment)</li>
  <li>Blue (RYB)</li>
  <li>Blue bell</li>
  <li>Blue-gray</li>
  <li>Blue-green</li>
  <li>Blue-green (color wheel)</li>
  <li>Blue jeans</li>
  <li>Blue sapphire</li>
  <li>Blue-violet</li>
  <li>Blue-violet (Crayola)</li>
  <li>Blue-violet (color wheel)</li>
  <li>Blue yonder</li>
  <li>Bluetiful</li>
  <li>Blush</li>
  <li>Bole</li>
  <li>Bone</li>
  <li>Bottle green</li>
  <li>Brandy</li>
  <li>Brick red</li>
  <li>Bright green</li>
  <li>Bright lilac</li>
  <li>Bright maroon</li>
  <li>Bright navy blue</li>
  <li>Bright yellow (Crayola)</li>
  <li>Brilliant rose</li>
</ul>

From the specification:

The grid-auto-columns and grid-auto-rows properties specify the size of tracks not assigned a size by grid-template-rows or grid-template-columns. If multiple track sizes are given, the pattern is repeated as necessary to find the size of the affected tracks.

For the repeat() idea it can only be used with grid-template-rows not grid-auto-rows but you don't have to because the grid-auto-rows was designed for this purpose "define the height of the remaining rows"

ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(95px, 1fr));
  grid-template-rows: auto auto repeat(300,0);
  overflow: hidden;
  padding: 0;
}

li {
  list-style: none;
  padding: 10px;
  border: 1px solid orange;
  overflow: hidden;
  margin: 0 5px 5px 0;
}

<h1><a href="https://en.wikipedia.org/wiki/List_of_colors:_A%E2%80%93F">Colors</a></h1>
<ul>
  <li>Android green</li>
  <li>Antique brass</li>
  <li>Antique bronze</li>
  <li>Antique fuchsia</li>
  <li>Antique ruby</li>
  <li>Antique white</li>
  <li>Ao (English)</li>
  <li>Apple green</li>
  <li>Apricot</li>
  <li>Aqua</li>
  <li>Aquamarine</li>
  <li>Arctic lime</li>
  <li>Army green</li>
  <li>Artichoke</li>
  <li>Arylide yellow</li>
  <li>Ash gray</li>
  <li>Asparagus</li>
  <li>Astronaut</li>
  <li>Atomic tangerine</li>
  <li>Auburn</li>
  <li>Aureolin</li>
  <li>Avocado</li>
  <li>Azure</li>
  <li>Azure (X11/web color)</li>
  <li>Baby blue</li>
  <li>Baby blue eyes</li>
  <li>Baby pink</li>
  <li>Baby powder</li>
  <li>Baker-Miller pink</li>
  <li>Banana Mania</li>
  <li>Barbie Pink</li>
  <li>Barn red</li>
  <li>Battleship grey</li>
  <li>Beau blue</li>
  <li>Beaver</li>
  <li>Beige</li>
  <li>B'dazzled blue</li>
  <li>Big dip o’ruby</li>
  <li>Bisque</li>
  <li>Bistre</li>
  <li>Bistre brown</li>
  <li>Bitter lemon</li>
  <li>Bitter lime</li>
  <li>Bittersweet</li>
  <li>Bittersweet shimmer</li>
  <li>Black</li>
  <li>Black bean</li>
  <li>Black chocolate</li>
  <li>Black coffee</li>
  <li>Black coral</li>
  <li>Black olive</li>
  <li>Black Shadows</li>
  <li>Blanched almond</li>
  <li>Blast-off bronze</li>
  <li>Bleu de France</li>
  <li>Blizzard blue</li>
  <li>Blond</li>
  <li>Blood red</li>
  <li>Blue</li>
  <li>Blue (Crayola)</li>
  <li>Blue (Munsell)</li>
  <li>Blue (NCS)</li>
  <li>Blue (Pantone)</li>
  <li>Blue (pigment)</li>
  <li>Blue (RYB)</li>
  <li>Blue bell</li>
  <li>Blue-gray</li>
  <li>Blue-green</li>
  <li>Blue-green (color wheel)</li>
  <li>Blue jeans</li>
  <li>Blue sapphire</li>
  <li>Blue-violet</li>
  <li>Blue-violet (Crayola)</li>
  <li>Blue-violet (color wheel)</li>
  <li>Blue yonder</li>
  <li>Bluetiful</li>
  <li>Blush</li>
  <li>Bole</li>
  <li>Bone</li>
  <li>Bottle green</li>
  <li>Brandy</li>
  <li>Brick red</li>
  <li>Bright green</li>
  <li>Bright lilac</li>
  <li>Bright maroon</li>
  <li>Bright navy blue</li>
  <li>Bright yellow (Crayola)</li>
  <li>Brilliant rose</li>
</ul>


问:
Range columns to fill combobox
I want to fill a ComboBox with column names.

For every option I try I get:

Error 380 Runtime RowSource.

In forums this seemed to work, but I need it for columns.

ComboBox1.Value = "Please Select an employee from the dropdown"
ComboBox1.RowSource = "Sheet1!A3:A" & Range("A" & Rows.Count).End(xlUp).Row
```

The blue headers are the ones I need in the comboBox, from A3:J3

答:
From the picture, it looks like your data is in a List Object. If so, it is very easy to grab the Headers from the list object, and turn them into an array. Once you have an array, you can insert the array into the ComboBox List like myComboBox.List = myArray.

Sub Example()
    'Get the List Object
    Dim myList As ListObject
    Set myList = Sheet1.ListObjects("List1") 'CHANGE "List1" TO MATCH YOUR TABLE'S NAME

    'Get the Headers
    Dim ListHeaders As Range
    Set ListHeaders = myList.HeaderRowRange

    'Create an empty Array
    Dim Headers() As String
    ReDim Headers(ListHeaders.Cells.Count - 1)

    'Fill the Array
    Dim i As Long
    For i = 0 To ListHeaders.Cells.Count - 1
        Headers(i) = ListHeaders.Cells(i + 1)
    Next

    'Put the Array into the ComboBox
    Me.ComboBox1.List = Headers

End Sub
```

Title: Range columns to fill combobox

Body:
I want to fill a ComboBox with column names.

For every option I try I get:

Error 380 Runtime RowSource.

In forums this seemed to work, but I need it for columns.

ComboBox1.Value = "Please Select an employee from the dropdown"
ComboBox1.RowSource = "Sheet1!A3:A" & Range("A" & Rows.Count).End(xlUp).Row

The blue headers are the ones I need in the comboBox, from A3:J3


问:
java lambda expression in sorting. diff between .sort() and Arrays.sort()
Please see the code below, on the fourth line, put the lambda expression in the .sort() method, it works fine.

The fifth line, using Arrays.sort() will report an error.
I would like to know where is the difference between the two. and how to properly use lambda expressions in Arrays.sort()

```<code>    var strs = new ArrayList<String>();
    strs.add("AA");
    strs.add("BB");
    strs.sort((a,b) -> b.compareTo(a)); // OK
    // Arrays.sort(strs, (a, b) ->  b.compareTo(a) ); // CAN NOT COMPILE java: no suitable method found for sort...
</code>```

Related questions:
using Arrays.sort with Lambda

答:
Arrays and lists are different so you can't pass an instance of one to a method expecting the other.  But the List interface has a sort() method that takes a Comparator. To sort a list,
try it like this. Strings implement the Comparable interface and their natural order is ascending. So just specify a reverse order Comparator for comparing.

```<code>var strs = new ArrayList<String>();
   strs.add("AA");
   strs.add("BB");

strs.sort(Comparator.reverseOrder());

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

prints

```<code>BB
AA
</code>```

Body:
Please see the code below, on the fourth line, put the lambda expression in the .sort() method, it works fine.

The fifth line, using Arrays.sort() will report an error.
I would like to know where is the difference between the two. and how to properly use lambda expressions in Arrays.sort()

    var strs = new ArrayList<String>();
    strs.add("AA");
    strs.add("BB");
    strs.sort((a,b) -> b.compareTo(a)); // OK
    // Arrays.sort(strs, (a, b) ->  b.compareTo(a) ); // CAN NOT COMPILE java: no suitable method found for sort...

Related questions:
using Arrays.sort with Lambda

Body:
Arrays and lists are different so you can't pass an instance of one to a method expecting the other.  But the List interface has a sort() method that takes a Comparator. To sort a list,
try it like this. Strings implement the Comparable interface and their natural order is ascending. So just specify a reverse order Comparator for comparing.

var strs = new ArrayList<String>();
   strs.add("AA");
   strs.add("BB");

strs.sort(Comparator.reverseOrder());

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

prints

BB
AA


问:
Extension's script does not wait for whole page to load before running
I've recently started working on a chrome extension which has to wait for a YouTube page to load before adding a button at a certain place in the already existing code.

I've used getElementById() to get the element, but most of the time my page doesn't have time to fully load that the script already finished.

I've checked many topics regarding this issue and stumbled across window.addEventListener('load', submitAction); which doesn't actually waits for the whole page to load, or at least it doesn't look like it. When I try to print the output of the getElementById()'s output, the result is null.

I've been trying to use other kind of event listeners, using it on document and not on window, trying to wait for  DOMContentLoaded as it looks like it's also waiting for the document to fully load but nothing actually waits for the whole page to load.

The most optimal thing I would like to do would be that the page loads, when the element I am looking for loads, I simply grab it, create a button, append it and it seamlessly appears in the page without any latency.

Am I doing something wrong here?*

Here's a sample of my code :

manifest.json :

```<code>{
    "name": "Name",
    "description": "Description.",
    "version": "1.0",
    "manifest_version": 2,
    "permissions": [
      "activeTab"
    ],
    "content_scripts": [
      {
        "matches": ["https://*.youtube.com/c/*"],
        "js": ["content-script.js"],
        "run_at": "document_idle"
      }
    ],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    }
}
</code>```

background.js :

```<code>chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
  if (changeInfo.status == 'complete') {
    window.onload = function() {
      chrome.tabs.executeScript({
        file: "content-script.js"
      });
    }
  }
})
</code>```

content-script.js :

```<code>window.addEventListener('load', submitAction);

function submitAction()
{
  var youtubeName = document.getElementById("channel-name")

  console.log("========================")
  console.log(youtubeName)
  console.log("========================")
}
</code>```

答:
Maybe it doesn't help, but try adding "defer" to your script tags:

```<code><script defer src="script_file_name.js"></script>
</code>```

defer makes your .js files to wait for the whole HTML to finish parsing.

Body:
I've recently started working on a chrome extension which has to wait for a YouTube page to load before adding a button at a certain place in the already existing code.

I've used getElementById() to get the element, but most of the time my page doesn't have time to fully load that the script already finished.

I've checked many topics regarding this issue and stumbled across window.addEventListener('load', submitAction); which doesn't actually waits for the whole page to load, or at least it doesn't look like it. When I try to print the output of the getElementById()'s output, the result is null.

I've been trying to use other kind of event listeners, using it on document and not on window, trying to wait for  DOMContentLoaded as it looks like it's also waiting for the document to fully load but nothing actually waits for the whole page to load.

The most optimal thing I would like to do would be that the page loads, when the element I am looking for loads, I simply grab it, create a button, append it and it seamlessly appears in the page without any latency.

Am I doing something wrong here?*

Here's a sample of my code :

manifest.json :

{
    "name": "Name",
    "description": "Description.",
    "version": "1.0",
    "manifest_version": 2,
    "permissions": [
      "activeTab"
    ],
    "content_scripts": [
      {
        "matches": ["https://*.youtube.com/c/*"],
        "js": ["content-script.js"],
        "run_at": "document_idle"
      }
    ],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    }
}

background.js :

chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
  if (changeInfo.status == 'complete') {
    window.onload = function() {
      chrome.tabs.executeScript({
        file: "content-script.js"
      });
    }
  }
})

content-script.js :

window.addEventListener('load', submitAction);

function submitAction()
{
  var youtubeName = document.getElementById("channel-name")

  console.log("========================")
  console.log(youtubeName)
  console.log("========================")
}

Body:
Maybe it doesn't help, but try adding "defer" to your script tags:

<script defer src="script_file_name.js"></script>

defer makes your .js files to wait for the whole HTML to finish parsing.


问:
How can I get a value from an if statement and work out the difference
I have a function that checks if a user has the app open or closed. If opened take the current time and store it in a variable, if the app is closed, do the same. then it should work out the difference and print it back.

I'm trying to work out how long the user has spent on the app.

I just not sure how to get it to work, I've tried to assign it to a global and use it from there but that did not work, I've tried sending the values to another function but I keep getting null returned.

What can I do to fix this?

*.dart

```<code>activeTimer(value) {
    print(value);

    if (value == true) {
      startTimer();
      print("TRUE 1");
      DateTime dateTimeStart = DateTime.now();
    } else {
      print("FALSE 1");
      stopTimer();
      DateTime dateTimeEnd = DateTime.now();
    };

  final differenceInDays = dateTimeEnd.difference(dateTimeStart).inMinutes;
    print(differenceInDays);

  }
</code>```

答:
I highly recommend you to use a Stream for this purpose.
For example:

```<code>Stream<int> tick({required int ticks}) {
return Stream.periodic(Duration(seconds: 1), (x) => ticks + x + 1)
    .take(ticks);
</code>```

}

That's very similar to what you can find in this Bloc Tutorial - link

Body:
I have a function that checks if a user has the app open or closed. If opened take the current time and store it in a variable, if the app is closed, do the same. then it should work out the difference and print it back.

I'm trying to work out how long the user has spent on the app.

I just not sure how to get it to work, I've tried to assign it to a global and use it from there but that did not work, I've tried sending the values to another function but I keep getting null returned.

What can I do to fix this?

*.dart

activeTimer(value) {
    print(value);

    if (value == true) {
      startTimer();
      print("TRUE 1");
      DateTime dateTimeStart = DateTime.now();
    } else {
      print("FALSE 1");
      stopTimer();
      DateTime dateTimeEnd = DateTime.now();
    };

  final differenceInDays = dateTimeEnd.difference(dateTimeStart).inMinutes;
    print(differenceInDays);

  }

Body:
I highly recommend you to use a Stream for this purpose.
For example:

Stream<int> tick({required int ticks}) {
return Stream.periodic(Duration(seconds: 1), (x) => ticks + x + 1)
    .take(ticks);

}

That's very similar to what you can find in this Bloc Tutorial - link


问:
Subset columns of sparse eigen matrix
I want to take subset columns of some sparse matrix (column-major)
As far as i know there are indexing stuff in Eigen.
But i cannot call it for sparse matrix:

```<code>Eigen::SparseMatrix<double> m;
std::vector<int> indices = {1, 5, 3, 6};
// error: type 'Eigen::SparseMatrix<double>' does not provide a call operator
m(Eigen::all, indices);
</code>```

Is there are any workaround?

UPD1
Explicitly specified that columns can be in arbitrary order.

答:
The SparseMatrix actually does not provide any operator(), so this cannot be done.

EDIT: The following was aimed at an older version of the question.

In case your actual use case also has the property that the columns you want to access are adjacent you can instead use

SparseMatrix<double,ColMajor> m(5,5);
int j = 1;
int number_of_columns=2;
m.middleCols(j,number_of_columns) = ...;
```
<p>There are also <code>m.leftCols(number_of_columns)</code> and <code>m.rightCols(number_of_columns)</code>
These are even writable, because the matrix is column-major.</p>
<p>All other block expressions are defined but read-only, see the corresponding Sparse Matrix documentation.</p>
<p>EDIT: To answer the updated question:
I guess you won't be able to avoid copying. With copying it can be done like this (not tested)</p>
<pre class="lang-cpp prettyprint-override"><code>Eigen::SparseMatrix<double> m;
std::vector<int> indices = {1, 5, 3, 6};
Eigen::SparseMatrix<double> column_subset(m.rows(),indices.size());
for(int j =0;j!=column_subset.cols();++j){
column_subset.col(j)=m.col(indices[j]);
}
</code>```

Title: Subset columns of sparse eigen matrix

Body:
I want to take subset columns of some sparse matrix (column-major)
As far as i know there are indexing stuff in Eigen.
But i cannot call it for sparse matrix:

Eigen::SparseMatrix<double> m;
std::vector<int> indices = {1, 5, 3, 6};
// error: type 'Eigen::SparseMatrix<double>' does not provide a call operator
m(Eigen::all, indices);

Is there are any workaround?

UPD1
Explicitly specified that columns can be in arbitrary order.

Body:
The SparseMatrix actually does not provide any operator(), so this cannot be done.

EDIT: The following was aimed at an older version of the question.

In case your actual use case also has the property that the columns you want to access are adjacent you can instead use

SparseMatrix<double,ColMajor> m(5,5);
int j = 1;
int number_of_columns=2;
m.middleCols(j,number_of_columns) = ...;

There are also m.leftCols(number_of_columns) and m.rightCols(number_of_columns)
These are even writable, because the matrix is column-major.

All other block expressions are defined but read-only, see the corresponding Sparse Matrix documentation.

EDIT: To answer the updated question:
I guess you won't be able to avoid copying. With copying it can be done like this (not tested)

Eigen::SparseMatrix<double> m;
std::vector<int> indices = {1, 5, 3, 6};
Eigen::SparseMatrix<double> column_subset(m.rows(),indices.size());
for(int j =0;j!=column_subset.cols();++j){
column_subset.col(j)=m.col(indices[j]);
}


问:
IIFE vs scope braces
Perhaps this is the stupidest question, but for IIFE, it mentions being used as a scope that would not pollute the global namespace.

Why would that be necessary as opposed to just using braces by itself to delimit scope (like in C)? For example:

{
    let firstVariable = 1;
    let secondVariable = 2;
}
console.log(firstVariable);```
</div>
</div>
</p>
<p>Instead of:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>(function () {
    let firstVariable = 1;
    let secondVariable = 2;
})();
console.log(firstVariable);</code>```

答:
JavaScript first appeared in 1995. The first specification edition was from 1997.

The specification that does include block scope is ES6 from 2015. Therefore, there has been no block scope for close to 20 years before it was introduced. IIFEs have existed in the mean time.

Also worth noting that block scope is not universal. It does work for let and const but not var

{
  var foo = 42;
}

console.log(foo); //output: 42

(function() {
  var bar = 42;
})();

console.log(bar); // error because `bar` does not exist in this context```
</div>
</div>
</p>
<p>Functions are also block-scoped as of ES6 but the rules around that are <em>weird</em>.</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>console.log("---- foo ----");

console.log("before block", foo); //output: undefined
{
  function foo() { return 42; }
}
console.log("after block", foo);  //output: function foo() { return 42; }

console.log("---- bar ----");

function bar() { return 1; }

console.log("before block", bar());   //output: 1
{
  function bar() { return 2; }
  console.log("inside block", bar()); //output: 2
}
console.log("after block ", bar());   //output: 2

console.log("---- baz ----");

{
  function baz() { return 1; }

  console.log("before inner block", baz());   //output: 1
  {
    function baz() { return 2; }
    console.log("inside inner block", baz()); //output: 2
  }
  console.log("after inner block ", baz());   //output: 1
}</code>```

.as-console-wrapper { max-height: 100% !important }```

Title: IIFE vs scope braces

Body:
Perhaps this is the stupidest question, but for IIFE, it mentions being used as a scope that would not pollute the global namespace.

Why would that be necessary as opposed to just using braces by itself to delimit scope (like in C)? For example:

{
    let firstVariable = 1;
    let secondVariable = 2;
}
console.log(firstVariable);

Instead of:

(function () {
    let firstVariable = 1;
    let secondVariable = 2;
})();
console.log(firstVariable);

Body:
JavaScript first appeared in 1995. The first specification edition was from 1997.

The specification that does include block scope is ES6 from 2015. Therefore, there has been no block scope for close to 20 years before it was introduced. IIFEs have existed in the mean time.

Also worth noting that block scope is not universal. It does work for let and const but not var

{
  var foo = 42;
}

console.log(foo); //output: 42

(function() {
  var bar = 42;
})();

console.log(bar); // error because `bar` does not exist in this context

Functions are also block-scoped as of ES6 but the rules around that are weird.

console.log("---- foo ----");

console.log("before block", foo); //output: undefined
{
  function foo() { return 42; }
}
console.log("after block", foo);  //output: function foo() { return 42; }

console.log("---- bar ----");

function bar() { return 1; }

console.log("before block", bar());   //output: 1
{
  function bar() { return 2; }
  console.log("inside block", bar()); //output: 2
}
console.log("after block ", bar());   //output: 2

console.log("---- baz ----");

{
  function baz() { return 1; }

  console.log("before inner block", baz());   //output: 1
  {
    function baz() { return 2; }
    console.log("inside inner block", baz()); //output: 2
  }
  console.log("after inner block ", baz());   //output: 1
}

.as-console-wrapper { max-height: 100% !important }