问:
.NET Core Service Layer or DAO Scoped, or both?
When creating a .NET application where the controller calls a service, then the service calls a DAO for the database work, and I'm using Entity Framework Core 6.0 for the database services, do I also add the service layer objects in ConfigureServices, or just the data layer, and pass them in to constructors?

I'm not sure this is exactly a preference, rather I'm worried about multithreading, specifically.

The scheme is: API -> Controller -> Service -> DAO -> Database then back for the result.

Sample code:

```<code>       public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContext<CRM_MSCRMContext>();
                services.AddScoped<HomeService>();
            }

</code>```

See above, I've added both the service that calls the context, as well as the context.

I'm injecting the DAO using the constructor:

Sample code:

```<code>
  public CRMDAO(CRM_MSCRMContext crmContext)
  {
     _crmContext = crmContext;
  }
</code>```

And I could be injecting the service into the controller, if I add to Scoped. Otherwise I think I'm just instantiating new in the constructor anyway:

```<code>
  public HomeController(HomeService homeService)
  {
     _homeService = homeService;
  }
</code>```

or I could use a constructor and forget injection here:

```<code> public HomeController()
  {
     _homeService = new HomeService();
  }
</code>```

Why would one be better than the other from a multithreading or database connection standpoint? I understand that this is going to be scoped per-request, so maybe it's no different than using the constructor to New the service object on every request anyway from the controller?

Thank you,
Dan Chase

答:
OK so after reading documentation and experimenting, I found it seems to be all or nothing. I had to add everything in ConfigureServices, all DAO's and all Services, as well as all Contexts. Otherwise I kept getting "Unable to resolve while attempting to activate" errors. I also had to move everything to an Interface, or it doesn't seem to work at all.

If anyone has any tips let me know, but I figured best to answer my own question than to delete, because someone might be able to fill in more info.

Body:
When creating a .NET application where the controller calls a service, then the service calls a DAO for the database work, and I'm using Entity Framework Core 6.0 for the database services, do I also add the service layer objects in ConfigureServices, or just the data layer, and pass them in to constructors?

I'm not sure this is exactly a preference, rather I'm worried about multithreading, specifically.

The scheme is: API -> Controller -> Service -> DAO -> Database then back for the result.

Sample code:

       public void ConfigureServices(IServiceCollection services)
            {
                services.AddDbContext<CRM_MSCRMContext>();
                services.AddScoped<HomeService>();
            }

See above, I've added both the service that calls the context, as well as the context.

I'm injecting the DAO using the constructor:

Sample code:

  public CRMDAO(CRM_MSCRMContext crmContext)
  {
     _crmContext = crmContext;
  }

And I could be injecting the service into the controller, if I add to Scoped. Otherwise I think I'm just instantiating new in the constructor anyway:

  public HomeController(HomeService homeService)
  {
     _homeService = homeService;
  }

or I could use a constructor and forget injection here:

 public HomeController()
  {
     _homeService = new HomeService();
  }

Why would one be better than the other from a multithreading or database connection standpoint? I understand that this is going to be scoped per-request, so maybe it's no different than using the constructor to New the service object on every request anyway from the controller?

Thank you,
Dan Chase


来源: stackexchange

问:
Cannot open pdf file downloaded from server using Express and Node Js
I am trying to send a pdf file hosted on the server to the client, to be downloaded from the browser. I am using express and node js.

The code on the server is :

```<code>app.get('/files', async (req, res) => {
     res.sendFile(__dirname + '/boarding-pass.pdf');
    });
</code>```

The code on the client (react js) is :

```<code>const handleClick = async () => {
    const response = await axios({
        url: 'http://localhost:4000/files',
       // url: '/static/boarding-pass.pdf',
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/pdf',
            'Authorization': 'Basic d29vZG1hYzpXb29kbWFjOTI3IQ=='
        },
        responseType: 'arraybuffer',
        //responseType: 'blob', // important
    });

console.log('response', response);
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'bp.pdf');
    document.body.appendChild(link);
    link.click();
}

export default () => <div><Button onClick={() => handleClick()}>Download file</Button></div>
</code>```

If I try to open the file on the server (I am on a Mac), the file is opened correctly and I see the content. However when I download the file from the browser, it gets someway corrupted or truncated, or it is missing something, because I can not open it, and I am getting the message that it is not a valid file, although I can see that the size of both files in the file system is the same, but if I inspect the binaries with an utility, I can see both files are different..

Can someone tell me what I am missing or provide an small working example?

Thank you

答:
Solution is much easier then we thought thanks for Edo_M

The key is res => res.blob() this will make the job for you.

My backend representation (Nodejs + express):

```<code>...
module.exports=function(app){
    // GET download specified pdf file
    app.get('/getpdf/:uuid', middlewarefunc.authenticateToken, (req, res) => {

        if(!req.params.uuid) return res.status(400).json({error:"Missing UUID param!"});

        res.setHeader('Content-Type', 'application/pdf');

        res.setHeader("Content-Disposition", "attachment");

        res.download(`./${req.params.uuid}`, (err)=>{
            console.log("Error: ", err);
        });
    });
}
...
</code>```

My frontend solution (tested in chrome):

```<code>...
function handleDownload(e, uuid){
  e.preventDefault();
    fetch(`${process.env.REACT_APP_SERVER}/getpdf/${uuid}`,
      {
        method: 'GET',
        headers: {
          'Accept': 'application/pdf',
          'Authorization': 'Bearer ' + session.accessToken,
          'Content-Type' : 'application/json'
        }
      })
      .then(res=>res.blob())
      .then(response => {
        var fileURL = URL.createObjectURL(response);
        window.open(fileURL);
      })
      .catch(err => {
        console.error(err);
        alert(err.error);
      });
...

// place a button to anywhere with onClick:
<button  onClick={(e) => handleDownload(e, pdf_uuid)}>Download PDF</button>

...
</code>```

You will get a new tab/window in the browser with the requested PDF content.

ContentLicense: CC BY-SA 4.0

Body:
I am trying to send a pdf file hosted on the server to the client, to be downloaded from the browser. I am using express and node js.

The code on the server is :

app.get('/files', async (req, res) => {
     res.sendFile(__dirname + '/boarding-pass.pdf');
    });

The code on the client (react js) is :

const handleClick = async () => {
    const response = await axios({
        url: 'http://localhost:4000/files',
       // url: '/static/boarding-pass.pdf',
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/pdf',
            'Authorization': 'Basic d29vZG1hYzpXb29kbWFjOTI3IQ=='
        },
        responseType: 'arraybuffer',
        //responseType: 'blob', // important
    });

console.log('response', response);
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'bp.pdf');
    document.body.appendChild(link);
    link.click();
}

export default () =>
<Button onClick={() => handleClick()}>Download file</Button>

If I try to open the file on the server (I am on a Mac), the file is opened correctly and I see the content. However when I download the file from the browser, it gets someway corrupted or truncated, or it is missing something, because I can not open it, and I am getting the message that it is not a valid file, although I can see that the size of both files in the file system is the same, but if I inspect the binaries with an utility, I can see both files are different..

Can someone tell me what I am missing or provide an small working example?

Thank you

Body:
Solution is much easier then we thought thanks for Edo_M

The key is res => res.blob() this will make the job for you.

My backend representation (Nodejs + express):

...
module.exports=function(app){
    // GET download specified pdf file
    app.get('/getpdf/:uuid', middlewarefunc.authenticateToken, (req, res) => {

        if(!req.params.uuid) return res.status(400).json({error:"Missing UUID param!"});

        res.setHeader('Content-Type', 'application/pdf');

        res.setHeader("Content-Disposition", "attachment");

        res.download(`./${req.params.uuid}`, (err)=>{
            console.log("Error: ", err);
        });
    });
}
...

My frontend solution (tested in chrome):

...
function handleDownload(e, uuid){
  e.preventDefault();
    fetch(`${process.env.REACT_APP_SERVER}/getpdf/${uuid}`,
      {
        method: 'GET',
        headers: {
          'Accept': 'application/pdf',
          'Authorization': 'Bearer ' + session.accessToken,
          'Content-Type' : 'application/json'
        }
      })
      .then(res=>res.blob())
      .then(response => {
        var fileURL = URL.createObjectURL(response);
        window.open(fileURL);
      })
      .catch(err => {
        console.error(err);
        alert(err.error);
      });
...

// place a button to anywhere with onClick:
<button  onClick={(e) => handleDownload(e, pdf_uuid)}>Download PDF</button>

...

You will get a new tab/window in the browser with the requested PDF content.


问:
How to filter in the table (so that they end up at the bottom of the table) the elements that belong to the "Film" section
I have a set of elements. Some of these are part of section "Film", others of section "Video" and still others of section "VideoYoutube". There is a special column that defines this Section.

The elements in the table that are part of section "Film" must be placed at the bottom of the table.

To be able to put the elements at the bottom of the table I know that you have to use the command:

insertRow(-1);

Since my table is dynamic, how can I set what I want?

Items.forEach(function (item) {
                    let child = document.createElement("tr");
                    child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`;
                    table.appendChild(child);
                })```
<pre class="snippet-code-html lang-html prettyprint-override"><code>    <table id="my-table" width="90%">
            <tr>
                <th>Id</th>
                <th>Title</th>
                <th>Image</th>
                <th>Section</th>
                <th>Date</th>
            </tr>

        </table></code>```

To understand better, I have to filter by Film only

Example to understand

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}]
itemarr.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table></code>```

答:
You can filter your object based on a property (section).  Here I show how to do that with the "Film" value.

Now just do this for each in whichever order you want.

This is very basic as a example you can work from and this can be much more "elegant" by calling for example a function and passing the "section" name and using it, setting an object with the "orders" of these and processing that, things like that.

let itemarr = [{
    id: 1,
    title: "image 1",
    image: "url 1",
    section: "Film",
    date: "date 1",
  }, {
    id: 2,
    title: "image 2",
    image: "url 2",
    section: "Video",
    date: "date 2",
  },
  {
    id: 3,
    title: "image 3",
    image: "url 2",
    section: "Film",
    date: "date 2",
  },
  {
    id: 4,
    title: "image 4",
    image: "url 2",
    section: "Video",
    date: "date 2",
  }
];
const resultsFilm = itemarr.filter(obj => {
  return obj.section === "Film";
});
resultsFilm.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table></code>```

A bit more "elegant" solution using some objects and functions to process them by sorting in the order we specified.

let itemarr = [{
    id: 1,
    title: "image 1",
    image: "url 1",
    section: "Film",
    date: "date 1",
  }, {
    id: 2,
    title: "image 2",
    image: "url 2",
    section: "Video",
    date: "date 2",
  },
  {
    id: 3,
    title: "image 3",
    image: "url 2",
    section: "Film",
    date: "date 2",
  },
  {
    id: 4,
    title: "image 4",
    image: "url 2",
    section: "Video",
    date: "date 2",
  }
];
let sectionOrder = [{
  section: "Video",
  order: 1
}, {
  section: "Film",
  order: 5
}, {
  section: "YouTube",
  order: 2
}];

function showSection(sectionName) {
  const resultsFiltered = itemarr.filter(obj => {
    return obj.section === sectionName;
  });
  resultsFiltered.forEach(function(item) {
    let child = document.querySelector('table').insertRow(-1)
    child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

  });
}
// sort by the order
sectionOrder.sort((a, b) => (a.order > b.order) ? 1 : -1);
//console.log(sectionOrder);
//process sections in the order we sorted, use that to refer to the data.
sectionOrder.forEach(function(sec) {
  showSection(sec.section);
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table></code>```

Body:
I have a set of elements. Some of these are part of section "Film", others of section "Video" and still others of section "VideoYoutube". There is a special column that defines this Section.

The elements in the table that are part of section "Film" must be placed at the bottom of the table.

To be able to put the elements at the bottom of the table I know that you have to use the command:

insertRow(-1);

Since my table is dynamic, how can I set what I want?

Items.forEach(function (item) {
                    let child = document.createElement("tr");
                    child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`;
                    table.appendChild(child);
                })

                Id
                Title
                Image
                Section
                Date

To understand better, I have to filter by Film only

Example to understand

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}]
itemarr.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

})

    Id
    Title
    Image
    Section
    Date

Body:
You can filter your object based on a property (section).  Here I show how to do that with the "Film" value.

Now just do this for each in whichever order you want.

This is very basic as a example you can work from and this can be much more "elegant" by calling for example a function and passing the "section" name and using it, setting an object with the "orders" of these and processing that, things like that.

let itemarr = [{
    id: 1,
    title: "image 1",
    image: "url 1",
    section: "Film",
    date: "date 1",
  }, {
    id: 2,
    title: "image 2",
    image: "url 2",
    section: "Video",
    date: "date 2",
  },
  {
    id: 3,
    title: "image 3",
    image: "url 2",
    section: "Film",
    date: "date 2",
  },
  {
    id: 4,
    title: "image 4",
    image: "url 2",
    section: "Video",
    date: "date 2",
  }
];
const resultsFilm = itemarr.filter(obj => {
  return obj.section === "Film";
});
resultsFilm.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    <td>${item.id}</td>
                    <td>${item.title}</td>
                    <td>${item.image}</td>
                    <td>${item.section}</td>
                    <td>${item.date}</td>`

});

<table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table>

A bit more "elegant" solution using some objects and functions to process them by sorting in the order we specified.

let itemarr = [{
    id: 1,
    title: "image 1",
    image: "url 1",
    section: "Film",
    date: "date 1",
  }, {
    id: 2,
    title: "image 2",
    image: "url 2",
    section: "Video",
    date: "date 2",
  },
  {
    id: 3,
    title: "image 3",
    image: "url 2",
    section: "Film",
    date: "date 2",
  },
  {
    id: 4,
    title: "image 4",
    image: "url 2",
    section: "Video",
    date: "date 2",
  }
];
let sectionOrder = [{
  section: "Video",
  order: 1
}, {
  section: "Film",
  order: 5
}, {
  section: "YouTube",
  order: 2
}];

function showSection(sectionName) {
  const resultsFiltered = itemarr.filter(obj => {
    return obj.section === sectionName;
  });
  resultsFiltered.forEach(function(item) {
    let child = document.querySelector('table').insertRow(-1)
    child.innerHTML = `
                    <td>${item.id}</td>
                    <td>${item.title}</td>
                    <td>${item.image}</td>
                    <td>${item.section}</td>
                    <td>${item.date}</td>`

  });
}
// sort by the order
sectionOrder.sort((a, b) => (a.order > b.order) ? 1 : -1);
//console.log(sectionOrder);
//process sections in the order we sorted, use that to refer to the data.
sectionOrder.forEach(function(sec) {
  showSection(sec.section);
});

<table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table>


问:
Fail2ban not sending email notifications
My CentOS server has postfix as MTA and it’s working.
When I type the command mail -s "testing" <my gmail address>, I receive the email.

However, Fail2ban is unable to send emails to my gmail address when an IP gets banned. I’m probably missing some configuration in jail.conf.

Here is part of my jail.conf file:

```<code>destemail = myaddress@gmail.com
sendername = fail2ban
mta = sendmail
protocol = tcp
action = %(action_mwl)s
</code>```

I already tried mta = postfix and it didn’t work.

Thanks in advance for your help.

EDIT: I was able to make it work. None of the configuration above is correct for my fail2ban v0.8.10 and my linux CentOS 6. In fact, I removed all the lines above (garbage).

I found a pre-defined action in /etc/fail2ban/action.d/mail.conf file.
I noticed this action uses "mail -s" command which works on my server.
So, I decided to use this action in my jail.conf file as such:

```<code>[ssh-iptables]
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
           mail[name=ssh, dest=my-address@gmail.com]
logpath  = /var/log/secure
maxretry = 5
</code>```

The only thing that needs to be change to get an email from fail2ban is to add that line below “action” that starts with “mail.” Very simple and easy.

答:
All of the above did not work for me.

What worked for me was adding second line under action =....

to be:

```<code>sendmail[mailcmd='/usr/sbin/sendmail -f "<sender>" "<dest>"', dest="email@recipient.com", sender="fail2ban", sendername="Fail2Ban", name="jail_name"]
</code>```

Note: You may do so for various jails.

Also note, that if you would like to get an email notification for ModSecurity, you can do so, by setting a Fail2Ban jail for ModSecurity, and then get the email notifications.

ContentLicense: CC BY-SA 3.0

Body:
My CentOS server has postfix as MTA and it’s working.
When I type the command mail -s "testing" <my gmail address>, I receive the email.

However, Fail2ban is unable to send emails to my gmail address when an IP gets banned. I’m probably missing some configuration in jail.conf.

Here is part of my jail.conf file:

destemail = myaddress@gmail.com
sendername = fail2ban
mta = sendmail
protocol = tcp
action = %(action_mwl)s

I already tried mta = postfix and it didn’t work.

Thanks in advance for your help.

EDIT: I was able to make it work. None of the configuration above is correct for my fail2ban v0.8.10 and my linux CentOS 6. In fact, I removed all the lines above (garbage).

I found a pre-defined action in /etc/fail2ban/action.d/mail.conf file.
I noticed this action uses "mail -s" command which works on my server.
So, I decided to use this action in my jail.conf file as such:

[ssh-iptables]
enabled  = true
filter   = sshd
action   = iptables[name=SSH, port=ssh, protocol=tcp]
           mail[name=ssh, dest=my-address@gmail.com]
logpath  = /var/log/secure
maxretry = 5

The only thing that needs to be change to get an email from fail2ban is to add that line below “action” that starts with “mail.” Very simple and easy.

Body:
All of the above did not work for me.

What worked for me was adding second line under action =....

to be:

sendmail[mailcmd='/usr/sbin/sendmail -f "<sender>" "<dest>"', dest="email@recipient.com", sender="fail2ban", sendername="Fail2Ban", name="jail_name"]

Note: You may do so for various jails.

Also note, that if you would like to get an email notification for ModSecurity, you can do so, by setting a Fail2Ban jail for ModSecurity, and then get the email notifications.


问:
Django redirect user to shopping cart after item is added
In a Django / python website, I have a button that adds the selected item to the shopping cart but I need the user to then be redirected to the cart, but nothing I've tried has worked.  Any help would be appreciated. I'm a novice at this.

The button code:

```<code><button
    data-product="{{product.id}}"
    data-action="add"
    class="btn button button--primary add-btn update-cart">
    Book this event
</button>
</code>```

答:
You can do something like this:

#html

```<code><button
    data-product="{{product.id}}"
    data-action="add"
    class="btn button button--primary add-btn update-cart"
    onclick="window.open('{% url 'cartURL' pID=product.id %}')"
    >
    Book this event
</button>
</code>```

#url.py

add this url pattern

```<code>path('cartURL/<str:pID>/', views.cartView, name='cartURL')
</code>```

#view.py

```<code>def cartView(request,pID):
   #add productID and user data in cache,db or session as per your requirement
   return(request,'cart.html',data)
</code>```

Body:
In a Django / python website, I have a button that adds the selected item to the shopping cart but I need the user to then be redirected to the cart, but nothing I've tried has worked.  Any help would be appreciated. I'm a novice at this.

The button code:

<button
    data-product="{{product.id}}"
    data-action="add"
    class="btn button button--primary add-btn update-cart">
    Book this event
</button>

Body:
You can do something like this:

#html

<button
    data-product="{{product.id}}"
    data-action="add"
    class="btn button button--primary add-btn update-cart"
    onclick="window.open('{% url 'cartURL' pID=product.id %}')"
    >
    Book this event
</button>

#url.py

add this url pattern

path('cartURL/<str:pID>/', views.cartView, name='cartURL')

#view.py

def cartView(request,pID):
   #add productID and user data in cache,db or session as per your requirement
   return(request,'cart.html',data)


问:
Adding all string constants from a class to a List of string constants in C#
I have a class,

```<code>        public static class Permissions
        {
            public const string AccessRightFormAdmin = "TEST1";
            public const string AccessRightExperimental = "TEST2";
        }
</code>```

I want to have List<string> myConsts = new List<string>; such that, myConsts contains all the string constants from the Permissions class. How can I achieve this in C#?

答:
Instead of string, better to use KeyValuePair, this way constants can be used  the same way as enumerations.

```<code>List<KeyValuePair<string,string>> consts = typeof(Permission).GetFields()
.Select(p => new KeyValuePair<string,string> ( p.Name, (string)p.GetValue(null))).ToList();
</code>```

result

```<code>AccessRightFormAdmin    TEST1
AccessRightExperimental TEST2
</code>```

Body:
I have a class,

        public static class Permissions
        {
            public const string AccessRightFormAdmin = "TEST1";
            public const string AccessRightExperimental = "TEST2";
        }

I want to have List<string> myConsts = new List<string>; such that, myConsts contains all the string constants from the Permissions class. How can I achieve this in C#?

Body:
Instead of string, better to use KeyValuePair, this way constants can be used  the same way as enumerations.

List<KeyValuePair<string,string>> consts = typeof(Permission).GetFields()
.Select(p => new KeyValuePair<string,string> ( p.Name, (string)p.GetValue(null))).ToList();

result

AccessRightFormAdmin    TEST1
AccessRightExperimental TEST2


问:
How to redirect to a specific screen after main.dart upon reopening app from foreground?
I have a Flutter application with push notifications through flutter_local_notifications. When the app is open, I press the "Home" button on the iPhone 12 emulator. Then, when a push notification is pressed, I can see what the payload of said notification is in main.dart with a listener:

```<code>    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
      onSelectNotification: (String? payload) async {

        if (payload != null) {
          debugPrint('notification payload: $payload');

        }

  });
</code>```

What I'm trying to do is redirect to a specific screen if the payload (String) is equal to a specific value like so:

```<code>await flutterLocalNotificationsPlugin.initialize(initializationSettings,
          onSelectNotification: (String? payload) async {

            if (payload != null) {
              debugPrint('notification payload: $payload');

            }

            if (payload == "test") {
               // navigate to test screen instead of home screen
            }

      });
</code>```

One of the issues I'm seeing is that "context" is unavailable, even after importing dependency. Is this functionality possible?

答: Alternatively, you could use a flutter dynamic links</p>

Body:
I have a Flutter application with push notifications through flutter_local_notifications. When the app is open, I press the "Home" button on the iPhone 12 emulator. Then, when a push notification is pressed, I can see what the payload of said notification is in main.dart with a listener:

    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
      onSelectNotification: (String? payload) async {

        if (payload != null) {
          debugPrint('notification payload: $payload');

        }

  });

What I'm trying to do is redirect to a specific screen if the payload (String) is equal to a specific value like so:

await flutterLocalNotificationsPlugin.initialize(initializationSettings,
          onSelectNotification: (String? payload) async {

            if (payload != null) {
              debugPrint('notification payload: $payload');

            }

            if (payload == "test") {
               // navigate to test screen instead of home screen
            }

      });

One of the issues I'm seeing is that "context" is unavailable, even after importing dependency. Is this functionality possible?


问:
Any way to do a local CVS proxy/server?
I have an online CVS repository that I need to check code into. However, the server is outside my control and is often down.

So, is there a way to set up some sort of local CVS server/proxy such that I can check my code into the local CVS server regularly and have the local CVS server batch commit the changes to the online CVS repo periodically?

The local repository could possibly run some other SCM system, if that was necessary to prevent conflict with CVS. Online commits could possibly be done manually, or via cron. I'm open to suggestions.

I guess that my main concern would be the problems faced in trying to set up some sort of repository 'hierarchy'.

PS: I'm running Linux all along the 'hierarchy'.

Edit: Found a similar item here.

答: I think you should consider using a distributed source management system such as git or mercurial which support this kind of decentralized source control.</p>

OwnerDisplayName: sybreon

ContentLicense: CC BY-SA 2.5

Title: Any way to do a local CVS proxy/server?

LastEditorDisplayName: sybreon

OwnerDisplayName: Razispio


问:
What is true and false and & | used for?
I am very new to c programming and we are studying and/or truth tables. I get the general idea of how to do something like C & 5 would come out to 4, but I am very confused on the purpose of this? What is the end goal with truths and falses? What is the question you are seeking to answer when you evaluate such expressions? I'm sorry if this is dumb question but I feel like it is so stupid that no one has a clear answer for it

答:
You need to understand the difference between & and && , they are very different things.

```<code>`&` is a bitwise operation. 0b1111 & 0b1001 = 0b1001
</code>```

ie perform a logical and on each bit in a value. You give the example

```<code>0x0C & 0x05 = 0b00001100 & 0b00000101 = 0b00000100 = 4
</code>```

&& is a way of combining logical tests, its close the the english word 'and'

```<code> if(a==4 && y ==9) xxx();
</code>```

xxx will only be executed it x is 4 and y is 9

What creates confusion is that logical values in C map to 0 (false) and not 0 (true). So for example try this

```<code> int a = 6;
 int j = (a == 4);
</code>```

you will see that j is 0 (because the condition a==4 is false.

So you will see things like this

```<code>if(a & 0x01) yyy();
</code>```

this performs the & operation and looks to see if the result is zero or not. So  yyy will be executed if the last bit is one, ie if its odd

Body:
You need to understand the difference between & and && , they are very different things.

`&` is a bitwise operation. 0b1111 & 0b1001 = 0b1001

ie perform a logical and on each bit in a value. You give the example

0x0C & 0x05 = 0b00001100 & 0b00000101 = 0b00000100 = 4

&& is a way of combining logical tests, its close the the english word 'and'

 if(a==4 && y ==9) xxx();

xxx will only be executed it x is 4 and y is 9

What creates confusion is that logical values in C map to 0 (false) and not 0 (true). So for example try this

 int a = 6;
 int j = (a == 4);

you will see that j is 0 (because the condition a==4 is false.

So you will see things like this

if(a & 0x01) yyy();

this performs the & operation and looks to see if the result is zero or not. So  yyy will be executed if the last bit is one, ie if its odd


问:
How to get numpy arrays output of .wav file format
I am new to Python, and I am trying to train my audio voice recognition model. I want to read a .wav file and get output of that .wav file into Numpy arrays. How can I do that?</p>

答:
This is possible with a few lines with wave (built in) and numpy (obviously). You don't need to use librosa, scipy or soundfile. The latest gave me problems reading wav files and it's the whole reason I'm writting here now.

import numpy as np
import wave

# Start opening the file with wave
with wave.open('filename.wav') as f:
    # Read the whole file into a buffer. If you are dealing with a large file
    # then you should read it in blocks and process them separately.
    buffer = f.readframes(f.getnframes())
    # Convert the buffer to a numpy array by checking the size of the sample
    # with in bytes. The output will be a 1D array with interleaved channels.
    interleaved = np.frombuffer(buffer, dtype=f'int{f.getsampwidth()*8}')
    # Reshape it into a 2D array separating the channels in columns.
    data = np.reshape(interleaved, (-1, f.getnchannels()))
```
<p>I like to pack it into a function that returns the sampling frequency and works with <code>pathlib.Path</code> objects. In this way it can be played using <code>sounddevice</code></p>
<pre class="lang-py prettyprint-override"><code># play_wav.py
import sounddevice as sd
import numpy as np
import wave

from typing import Tuple
from pathlib import Path

# Utility function that reads the whole `wav` file content into a numpy array
def wave_read(filename: Path) -> Tuple[np.ndarray, int]:
    with wave.open(str(filename), 'rb') as f:
        buffer = f.readframes(f.getnframes())
        inter = np.frombuffer(buffer, dtype=f'int{f.getsampwidth()*8}')
        return np.reshape(inter, (-1, f.getnchannels())), f.getframerate()

if __name__ == '__main__':
    # Play all files in the current directory
    for wav_file in Path().glob('*.wav'):
        print(f"Playing {wav_file}")
        data, fs = wave_read(wav_file)
        sd.play(data, samplerate=fs, blocking=True)
</code>```

Body:
This is possible with a few lines with wave (built in) and numpy (obviously). You don't need to use librosa, scipy or soundfile. The latest gave me problems reading wav files and it's the whole reason I'm writting here now.

import numpy as np
import wave

# Start opening the file with wave
with wave.open('filename.wav') as f:
    # Read the whole file into a buffer. If you are dealing with a large file
    # then you should read it in blocks and process them separately.
    buffer = f.readframes(f.getnframes())
    # Convert the buffer to a numpy array by checking the size of the sample
    # with in bytes. The output will be a 1D array with interleaved channels.
    interleaved = np.frombuffer(buffer, dtype=f'int{f.getsampwidth()*8}')
    # Reshape it into a 2D array separating the channels in columns.
    data = np.reshape(interleaved, (-1, f.getnchannels()))

I like to pack it into a function that returns the sampling frequency and works with pathlib.Path objects. In this way it can be played using sounddevice

# play_wav.py
import sounddevice as sd
import numpy as np
import wave

from typing import Tuple
from pathlib import Path

# Utility function that reads the whole `wav` file content into a numpy array
def wave_read(filename: Path) -> Tuple[np.ndarray, int]:
    with wave.open(str(filename), 'rb') as f:
        buffer = f.readframes(f.getnframes())
        inter = np.frombuffer(buffer, dtype=f'int{f.getsampwidth()*8}')
        return np.reshape(inter, (-1, f.getnchannels())), f.getframerate()

if __name__ == '__main__':
    # Play all files in the current directory
    for wav_file in Path().glob('*.wav'):
        print(f"Playing {wav_file}")
        data, fs = wave_read(wav_file)
        sd.play(data, samplerate=fs, blocking=True)


问:
How to compare pandas data frames and then "fill in" any missing rows with the other data frame
I have the following two arrays: Data and Baseline

```<code>Data
   Phase  ENSO  EJO
0      1    -1    2
1      1     0    2
2      1     1    2
3      2    -1    7
4      2     1    1

Baseline
   Phase  ENSO  EJO
0      1    -1    0.0
1      1     0    0.0
2      1     1    0.0
3      2    -1    0.0
4      2     0    0.0
5      2     1    0.0
</code>```

I want to alter the 'Data' data frame such that the "missing row" gets filled in by the Baseline data. Final result would look like this

```<code>Data
   Phase  ENSO  EJO
0      1    -1    2
1      1     0    2
2      1     1    2
3      2    -1    7
4      2     0    0
5      2     1    1
</code>```

答:
You could reindex Data by Baseline indices and fill the missing values with Baseline values using fillna.

```<code>Data = Data.reindex(Baseline.index).fillna(Baseline)
</code>```

Another option is to use combine_first:

```<code>Data = Data.combine_first(Baseline)
</code>```

Output:

```<code>   Phase  ENSO  EJO
0    1.0  -1.0  2.0
1    1.0   0.0  2.0
2    1.0   1.0  2.0
3    2.0  -1.0  7.0
4    2.0   1.0  1.0
5    2.0   1.0  0.0
</code>```

Body:
I have the following two arrays: Data and Baseline

Data
   Phase  ENSO  EJO
0      1    -1    2
1      1     0    2
2      1     1    2
3      2    -1    7
4      2     1    1

Baseline
   Phase  ENSO  EJO
0      1    -1    0.0
1      1     0    0.0
2      1     1    0.0
3      2    -1    0.0
4      2     0    0.0
5      2     1    0.0

I want to alter the 'Data' data frame such that the "missing row" gets filled in by the Baseline data. Final result would look like this

Data
   Phase  ENSO  EJO
0      1    -1    2
1      1     0    2
2      1     1    2
3      2    -1    7
4      2     0    0
5      2     1    1

Body:
You could reindex Data by Baseline indices and fill the missing values with Baseline values using fillna.

Data = Data.reindex(Baseline.index).fillna(Baseline)

Another option is to use combine_first:

Data = Data.combine_first(Baseline)

Output:

   Phase  ENSO  EJO
0    1.0  -1.0  2.0
1    1.0   0.0  2.0
2    1.0   1.0  2.0
3    2.0  -1.0  7.0
4    2.0   1.0  1.0
5    2.0   1.0  0.0


问:
summarize count with a condition
I have a data frame of counts in quadrats for a bunch of species in a bunch of years, but sometimes instead of counts, they are marked as "p" for "present." I want to average them while counting those p's as NA in the averaging, but also keep track of the number of p's there are in each species/year, so my question is, is there a way to use summarize(count) to count occurrences of P?

minimal example:

```<code>df <- data.frame(
  # years
  year = rep(1990:1992, each=3),
  # character vector of counts and p's
  count = c("p","p","2","1","5","4","7","p","4")
) %>%
  # numeric column of counts and NAs where P's should be
  mutate(count_numeric = as.numeric(count))

# summarize dataset
df %>%
  group_by(year) %>%
  summarize(number_quadrats = n(), # find total number of rows
            average_count = mean(count_numeric, na.rm=T)) # find average value

</code>```

but I want to add another line to the summarize that will just count the number of P's in each group. Something like this:

```<code>df %>%
  group_by(year) %>%
  summarize(number_quadrats = n(), # find total number of rows
            average_count = mean(count_numeric, na.rm=T),# find average value
            number_p = n(count == "p"))
</code>```

but that doesn't work.

Any advice appreciated.

Thanks!

答:
Something like this!</p>
```<code>df %>%
  group_by(year) %>%
  summarize(N = n(), number_quadrats = sum(count == 'p'),
            average_count = mean(count_numeric, na.rm=T))
</code>```
```<code>  year     N number_quadrats average_count
  <int> <int>           <int>         <dbl>
1  1990     3               2          2
2  1991     3               0          3.33
3  1992     3               1          5.5
</code>```

Title: summarize count with a condition

Body:
I have a data frame of counts in quadrats for a bunch of species in a bunch of years, but sometimes instead of counts, they are marked as "p" for "present." I want to average them while counting those p's as NA in the averaging, but also keep track of the number of p's there are in each species/year, so my question is, is there a way to use summarize(count) to count occurrences of P?

minimal example:

df <- data.frame(
  # years
  year = rep(1990:1992, each=3),
  # character vector of counts and p's
  count = c("p","p","2","1","5","4","7","p","4")
) %>%
  # numeric column of counts and NAs where P's should be
  mutate(count_numeric = as.numeric(count))

# summarize dataset
df %>%
  group_by(year) %>%
  summarize(number_quadrats = n(), # find total number of rows
            average_count = mean(count_numeric, na.rm=T)) # find average value

but I want to add another line to the summarize that will just count the number of P's in each group. Something like this:

df %>%
  group_by(year) %>%
  summarize(number_quadrats = n(), # find total number of rows
            average_count = mean(count_numeric, na.rm=T),# find average value
            number_p = n(count == "p"))

but that doesn't work.

Any advice appreciated.

Thanks!

Body:
Something like this!

df %>%
  group_by(year) %>%
  summarize(N = n(), number_quadrats = sum(count == 'p'),
            average_count = mean(count_numeric, na.rm=T))

  year     N number_quadrats average_count
  <int> <int>           <int>         <dbl>
1  1990     3               2          2
2  1991     3               0          3.33
3  1992     3               1          5.5


问:
how to simulate the hover of cursor python selenium
I want to click on button on web site, but this button appears after you put your cursor on the right place, otherwise you can not see this button. I tried to ignore that and do just normal click by finding the element by xpath. But that did not work out, there was mistake:

selenium.common.exceptions.ElementNotInteractableException: Message: element not
interactable: element has zero size

How to deal with that?

答:
This method worked well for me.</p>
```<code>def hoverXPATH(xpath):
   item = WebDriverWait(driver, 10)\
   .until(EC.visibility_of_element_located((By.XPATH, xpath)))
   ActionChains(driver).move_to_element(item).perform()
</code>```

Body:
This method worked well for me.

def hoverXPATH(xpath):
   item = WebDriverWait(driver, 10)\
   .until(EC.visibility_of_element_located((By.XPATH, xpath)))
   ActionChains(driver).move_to_element(item).perform()


问:
React Table is over SideBar
Is there any css property on a sidebar, or div, or table, that I'm missing to send my content underneath the Sidebar when opened?

I'm using react-data-table-component.

DataTable over SideBar:

DataTable Css:

```<code>#RTable-7 {
    text-align: center;
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border-collapse: collapse;
    border: 3px solid #ddd;
    width: 100%;
}

#RTable-7 td, #RTable-7 th {
    border: 1px solid #ddd;
    padding: 8px;
}

#RTable-7 tr:nth-child(even){background-color: #f2f2f2;}

#RTable-7 tr:hover {
    /* background-color: #ddd; */
    background-color: #eea2a2;
}

#RTable-7 th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: center;
    background-color: #4CAF50;
    color: white;
}
</code>```

SideBar Css:

```<code>.navbar {
    background-color: #060b26;
    height: 80px;
    display: flex;
    justify-content: start;
    align-items: center;
}

.nav-menu {
    background-color: #060b26;
    width: 250px;
    height: 100vh;
    display: flex;
    justify-content: center;
    position: fixed;
    top: 0;
    left: -100%;
    transition: 850ms;
}

.nav-menu.active {
    left: 0;
    transition: 350ms;
    position: absolute;
}

</code>```

答:
You need to give the z-index value of the .nav-menu a value higher than that of the table. Try this

```<code>.nav-menu {
    z-index: 10 !important; // increase it if 10 doesn't work
}
</code>```

Title: React Table is over SideBar

Body:
Is there any css property on a sidebar, or div, or table, that I'm missing to send my content underneath the Sidebar when opened?

I'm using react-data-table-component.

DataTable over SideBar:

DataTable Css:

#RTable-7 {
    text-align: center;
    font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
    border-collapse: collapse;
    border: 3px solid #ddd;
    width: 100%;
}

#RTable-7 td, #RTable-7 th {
    border: 1px solid #ddd;
    padding: 8px;
}

#RTable-7 tr:nth-child(even){background-color: #f2f2f2;}

#RTable-7 tr:hover {
    /* background-color: #ddd; */
    background-color: #eea2a2;
}

#RTable-7 th {
    padding-top: 12px;
    padding-bottom: 12px;
    text-align: center;
    background-color: #4CAF50;
    color: white;
}

SideBar Css:

.navbar {
    background-color: #060b26;
    height: 80px;
    display: flex;
    justify-content: start;
    align-items: center;
}

.nav-menu {
    background-color: #060b26;
    width: 250px;
    height: 100vh;
    display: flex;
    justify-content: center;
    position: fixed;
    top: 0;
    left: -100%;
    transition: 850ms;
}

.nav-menu.active {
    left: 0;
    transition: 350ms;
    position: absolute;
}

Body:
You need to give the z-index value of the .nav-menu a value higher than that of the table. Try this

.nav-menu {
    z-index: 10 !important; // increase it if 10 doesn't work
}


问:
Type hint for list with fixed start and end types but variable length
I'm wondering if there is a way to type hint when I expect a list that I know will end with bool and start with a variable number of ints?

What I'm effectively trying to do is

def f(xs: List[int, ..., bool]):
    pass
```

where ... is some variable number of ints (zero or more).

答:
If the number of ints is variable up to a certain limit, you can use the union of distinct Tuples as a workaround, as in:

from typing import Tuple, Union

TupleBoolLast = Union[
 Tuple[int, bool],
 Tuple[int, int, bool],
 Tuple[int, int, int, bool],
 Tuple[int, int, int, int, bool],
 Tuple[int, int, int, int, int, bool],
]

def f(xs: TupleBoolLast):
    pass
```
<p>Alternatively you could have a type that shows that your lists are a combination of ints and bools, though that does not enforce order:</p>
```ListIntBool = list[Union[int, bool]]

def f(xs: ListIntBool):
    pass
```

Body:
I'm wondering if there is a way to type hint when I expect a list that I know will end with bool and start with a variable number of ints?

What I'm effectively trying to do is

def f(xs: List[int, ..., bool]):
    pass

where ... is some variable number of ints (zero or more).

Body:
If the number of ints is variable up to a certain limit, you can use the union of distinct Tuples as a workaround, as in:

from typing import Tuple, Union

TupleBoolLast = Union[
 Tuple[int, bool],
 Tuple[int, int, bool],
 Tuple[int, int, int, bool],
 Tuple[int, int, int, int, bool],
 Tuple[int, int, int, int, int, bool],
]

def f(xs: TupleBoolLast):
    pass

Alternatively you could have a type that shows that your lists are a combination of ints and bools, though that does not enforce order:

ListIntBool = list[Union[int, bool]]

def f(xs: ListIntBool):
    pass


问:
Use zipTree as source set for building and static compiling

Background

Project Alice generates Java source code, stores it in sources.jar, then uploads it to a Maven repository. Project Bob pulls sources.jar down and needs to use it when compiling. Bob does not know that Alice exists, only where to find sources.jar.

Versions: JDK 11, Gradle 7.3.1, IntelliJ IDEA 2021.3.1

Problem

Making gradle (and IntelliJ's IDEA) build using source files embedded in a JAR file. To be clear, the JAR file contents resemble:

$ jar -tvf sources.jar
     0 Thu Feb 03 08:38:56 PST 2022 META-INF/
    52 Thu Feb 03 08:38:56 PST 2022 META-INF/MANIFEST.MF
     0 Thu Feb 03 08:38:30 PST 2022 com/
     0 Thu Feb 03 08:38:32 PST 2022 com/domain/
     0 Thu Feb 03 08:38:30 PST 2022 com/domain/package/
   938 Thu Feb 03 08:38:32 PST 2022 com/domain/package/SourceCode.java
```
<p>Solutions that extract the <code>.java</code> files from the <code>.jar</code> file introduce knock-on effects we'd like to avoid, including:</p>
<ul>
<li><strong>Editable.</strong> Extracted source files can be edited in the IDE. We'd like them to be read-only. We could add a task that sets the files read-only, but that feels like solving the wrong problem (added complexity).</li>
<li><strong>Synchronization.</strong> When a newly generated <code>sources.jar</code> is pulled down, we'll have to delete the extraction directory to remove any stale .java files that were preserved. If there was a way to avoid extraction, then the act of pulling down the new <code>sources.jar</code> file would ensure correctness (no added complexity). By unarchiving the .java files, it's possible to enter an inconsistent state:</li>
</ul>
<pre class="lang-sh prettyprint-override"><code>$ jar -tvf sources.jar | grep java$ | wc -l
61
$ find src/gen -name "*java" | wc -l
65
</code>```

If there was a way to treat sources.jar as a source directory without extracting the files, these knock-on effects disappear.

Attempts

A number of approaches have failed.

sourceSets

Changing sourceSets doesn't work:

```<code>sourceSets.main.java.srcDirs += "jar:${projectDir}/sources.jar!/"
</code>```

The error is:

Cannot convert URL 'jar:/home/user/dev/project/sources.jar!/' to a file.

Using a zipTree with sourceSets doesn't work, although the error message is telling:

```<code>sourceSets.main.java.srcDirs += zipTree(file: "${projectDir}/sources.jar")
</code>```

Error:

Cannot convert the provided notation to a File or URI.

The following types/formats are supported:

A URI or URL instance.

This was expected. What was unexpected was that URL instances are allowed, but seemingly not if embedded within a JAR file.

The following allows building Bob, but the IDE is unable to find SourceCode.java:

```<code>sourceSets.main.java.srcDirs += zipTree("${projectDir}/sources.jar").matching {
  include "com"
}
</code>```

build task

Modifying the build task to extract the generated code first partially works:

```<code>task codeGen {
  copy {
    from( zipTree( "${projectDir}/sources.jar" ) )
    into( "${buildDir}/src/gen/java" )
  }

  sourceSets.main.java.srcDirs += ["${buildDir}/src/gen/java"]
}

build { doFirst { codeGen } }
</code>```

The issue is that removing the build directory then prevents static compiles (because IDEA cannot find the generated source files). In any case, we don't want to extract the source files because of all the knock-on problems.

compile task

The following snippet also does not compile:

```<code>tasks.withType(JavaCompile) {
  source = zipTree(file: "${projectDir}/sources.jar")
}
</code>```

Not updating sourceSets means that the IDE cannot discover the source files.

sync task

We could extract the files into the main source directory, instead, such as:

```<code>def syncTask = task sync(type: Sync) {
    from zipTree("${projectDir}/sources.jar")
    into "${projectDir}/src/gen/java"

    preserve {
        include 'com/**'
        exclude 'META-INF/**'
    }
}

sourceSets.main.java.srcDir(syncTask)
</code>```

While that addresses the clean issue, we’re left with the original problems that we’d like to avoid.

Content Root

Setting the Content Root and marking the Source Folder from within IntelliJ IDEA works. The IDE updates .idea/misc.xml to include:

  <component name="FrameworkDetectionExcludesConfiguration">
    <file type="web" url="file://$PROJECT_DIR$" />
    <file type="web" url="jar://$PROJECT_DIR$/project/sources.jar!/" />
  </component>
```

In theory, the idea plugin may have the ability to set this value.

Question

How would you instruct Gradle to reference and build using source files that are stored in an external Java archive file when compiling a project (without extracting the archive) such that IDEA can statically resolve the source files, as well?

答:
We decided that extracting the jar file would be the best approach after all:

```<code>apply plugin: 'idea'

final GENERATED_JAR = "${projectDir}/sources.jar"
final GENERATED_DIR = "${buildDir}/generated/sources"

task extractSources(type: Sync) {
  from zipTree(GENERATED_JAR)
  into GENERATED_DIR
}

sourceSets.main.java.srcDir extractSources
clean.finalizedBy extractSources

idea.module.generatedSourceDirs += file(GENERATED_DIR)
</code>```

This:

Retains the generated sources after clean

Issues a warning in the IDE when modifying generated sources

Couples the build process to extracting source files

Reuses the build/generated/sources path

Keeps .jar file and .java files in synchronization

In effect, the following behaviours work as expected:

./gradlew clean -- leaves the extracted .java files intact, effectively

./gradlew build -- re-synchronizes .java files with .jar contents

Body:
Background

Project Alice generates Java source code, stores it in sources.jar, then uploads it to a Maven repository. Project Bob pulls sources.jar down and needs to use it when compiling. Bob does not know that Alice exists, only where to find sources.jar.

Versions: JDK 11, Gradle 7.3.1, IntelliJ IDEA 2021.3.1

Problem

Making gradle (and IntelliJ's IDEA) build using source files embedded in a JAR file. To be clear, the JAR file contents resemble:

$ jar -tvf sources.jar
     0 Thu Feb 03 08:38:56 PST 2022 META-INF/
    52 Thu Feb 03 08:38:56 PST 2022 META-INF/MANIFEST.MF
     0 Thu Feb 03 08:38:30 PST 2022 com/
     0 Thu Feb 03 08:38:32 PST 2022 com/domain/
     0 Thu Feb 03 08:38:30 PST 2022 com/domain/package/
   938 Thu Feb 03 08:38:32 PST 2022 com/domain/package/SourceCode.java

Solutions that extract the .java files from the .jar file introduce knock-on effects we'd like to avoid, including:

Editable. Extracted source files can be edited in the IDE. We'd like them to be read-only. We could add a task that sets the files read-only, but that feels like solving the wrong problem (added complexity).

Synchronization. When a newly generated sources.jar is pulled down, we'll have to delete the extraction directory to remove any stale .java files that were preserved. If there was a way to avoid extraction, then the act of pulling down the new sources.jar file would ensure correctness (no added complexity). By unarchiving the .java files, it's possible to enter an inconsistent state:

$ jar -tvf sources.jar | grep java$ | wc -l
61
$ find src/gen -name "*java" | wc -l
65

If there was a way to treat sources.jar as a source directory without extracting the files, these knock-on effects disappear.

Attempts

A number of approaches have failed.

sourceSets

Changing sourceSets doesn't work:

sourceSets.main.java.srcDirs += "jar:${projectDir}/sources.jar!/"

The error is:

Cannot convert URL 'jar:/home/user/dev/project/sources.jar!/' to a file.

Using a zipTree with sourceSets doesn't work, although the error message is telling:

sourceSets.main.java.srcDirs += zipTree(file: "${projectDir}/sources.jar")

Error:

Cannot convert the provided notation to a File or URI.

The following types/formats are supported:

A URI or URL instance.

This was expected. What was unexpected was that URL instances are allowed, but seemingly not if embedded within a JAR file.

The following allows building Bob, but the IDE is unable to find SourceCode.java:

sourceSets.main.java.srcDirs += zipTree("${projectDir}/sources.jar").matching {
  include "com"
}

build task

Modifying the build task to extract the generated code first partially works:

task codeGen {
  copy {
    from( zipTree( "${projectDir}/sources.jar" ) )
    into( "${buildDir}/src/gen/java" )
  }

  sourceSets.main.java.srcDirs += ["${buildDir}/src/gen/java"]
}

build { doFirst { codeGen } }

The issue is that removing the build directory then prevents static compiles (because IDEA cannot find the generated source files). In any case, we don't want to extract the source files because of all the knock-on problems.

compile task

The following snippet also does not compile:

tasks.withType(JavaCompile) {
  source = zipTree(file: "${projectDir}/sources.jar")
}

Not updating sourceSets means that the IDE cannot discover the source files.

sync task

We could extract the files into the main source directory, instead, such as:

def syncTask = task sync(type: Sync) {
    from zipTree("${projectDir}/sources.jar")
    into "${projectDir}/src/gen/java"

    preserve {
        include 'com/**'
        exclude 'META-INF/**'
    }
}

sourceSets.main.java.srcDir(syncTask)

While that addresses the clean issue, we’re left with the original problems that we’d like to avoid.

Content Root

Setting the Content Root and marking the Source Folder from within IntelliJ IDEA works. The IDE updates .idea/misc.xml to include:

  <component name="FrameworkDetectionExcludesConfiguration">
    <file type="web" url="file://$PROJECT_DIR$" />
    <file type="web" url="jar://$PROJECT_DIR$/project/sources.jar!/" />
  </component>

In theory, the idea plugin may have the ability to set this value.

Question

How would you instruct Gradle to reference and build using source files that are stored in an external Java archive file when compiling a project (without extracting the archive) such that IDEA can statically resolve the source files, as well?

Body:
We decided that extracting the jar file would be the best approach after all:

apply plugin: 'idea'

final GENERATED_JAR = "${projectDir}/sources.jar"
final GENERATED_DIR = "${buildDir}/generated/sources"

task extractSources(type: Sync) {
  from zipTree(GENERATED_JAR)
  into GENERATED_DIR
}

sourceSets.main.java.srcDir extractSources
clean.finalizedBy extractSources

idea.module.generatedSourceDirs += file(GENERATED_DIR)

This:

Retains the generated sources after clean

Issues a warning in the IDE when modifying generated sources

Couples the build process to extracting source files

Reuses the build/generated/sources path

Keeps .jar file and .java files in synchronization

In effect, the following behaviours work as expected:

./gradlew clean -- leaves the extracted .java files intact, effectively

./gradlew build -- re-synchronizes .java files with .jar contents


问:
Rotate square on its axis in HTML5 Canvas?
I want to create a function that rotates a square on its axis.

```<code>var halfWidth = canvas.width/2;
var halfHeight = canvas.height/2;

var x = halfWidth-10;
var y = halfHeight-10;
var w = 20;
var h = 20;
var deg = 45;

rotate(x, y, w, h, deg);

ctx.fillRect(x, y, w, h);
</code>```

The function:

```<code>function rotate(x, y, w, h, deg) {
    // ctx.translate() and ctx.rotate()
    // goes here.
}
</code>```

How to do this?

答:
If you don't want to deal with ctx.save() and all that, there's a brief way to calculate where each new point of the rotated square should be.

The following will draw a green square, and then draw a red square that has been rotated 22.5°.

const ctx = document.querySelector("canvas").getContext("2d");

ctx.fillStyle = "green";
ctx.fillRect(50, 50, 50, 50)

/**
 *
 * @returns {[number, number]} (x3, y3)
 */
function f(x1, y1, x2, y2, degrees) {
    const rad = degrees * Math.PI / 180;
    return [
        (x2 - x1) * Math.cos(rad) + x1 - (y2 - y1) * Math.sin(rad),
        (x2 - x1) * Math.sin(rad) + y1 + (y2 - y1) * Math.cos(rad)
    ]
}

ctx.fillStyle = "red";
const centre = 75;
/*
 * The centre of the square is at (75, 75)
 * The corner points are at:
 * (50, 50)
 * (100, 50)
 * (100, 100)
 * (50, 100)
 */

ctx.beginPath();
let [newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.moveTo(newX, newY);

[newX, newY] = f(centre, centre, 100, 50, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 100, 100, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 50, 100, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.lineTo(newX, newY);

ctx.fill();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><canvas width=200 height=200 style="background:gray"></canvas></code>```

I put this graphic together thinking it might help visualize what's going on.

Body:
I want to create a function that rotates a square on its axis.

var halfWidth = canvas.width/2;
var halfHeight = canvas.height/2;

var x = halfWidth-10;
var y = halfHeight-10;
var w = 20;
var h = 20;
var deg = 45;

rotate(x, y, w, h, deg);

ctx.fillRect(x, y, w, h);

The function:

function rotate(x, y, w, h, deg) {
    // ctx.translate() and ctx.rotate()
    // goes here.
}

How to do this?

Body:
If you don't want to deal with ctx.save() and all that, there's a brief way to calculate where each new point of the rotated square should be.

The following will draw a green square, and then draw a red square that has been rotated 22.5°.

const ctx = document.querySelector("canvas").getContext("2d");

ctx.fillStyle = "green";
ctx.fillRect(50, 50, 50, 50)

/**
 *
 * @returns {[number, number]} (x3, y3)
 */
function f(x1, y1, x2, y2, degrees) {
    const rad = degrees * Math.PI / 180;
    return [
        (x2 - x1) * Math.cos(rad) + x1 - (y2 - y1) * Math.sin(rad),
        (x2 - x1) * Math.sin(rad) + y1 + (y2 - y1) * Math.cos(rad)
    ]
}

ctx.fillStyle = "red";
const centre = 75;
/*
 * The centre of the square is at (75, 75)
 * The corner points are at:
 * (50, 50)
 * (100, 50)
 * (100, 100)
 * (50, 100)
 */

ctx.beginPath();
let [newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.moveTo(newX, newY);

[newX, newY] = f(centre, centre, 100, 50, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 100, 100, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 50, 100, 22.5);
ctx.lineTo(newX, newY);

[newX, newY] = f(centre, centre, 50, 50, 22.5);
ctx.lineTo(newX, newY);

ctx.fill();

<canvas width=200 height=200 style="background:gray"></canvas>

I put this graphic together thinking it might help visualize what's going on.


答:
enke's method is great - here's a solution that preserves the original datatypes:

```<code>Data = pd.concat([Data, Baseline[~Baseline.index.isin(Data.index)]])
</code>```

Output:

```<code>>>> Data
   Phase  ENSO  EJO
0      1    -1  2.0
1      1     0  2.0
2      1     1  2.0
3      2    -1  7.0
4      2     1  1.0
5      2     1  0.0
</code>```

Title: How to compare pandas data frames and then "fill in" any missing rows with the other data frame

Body:
enke's method is great - here's a solution that preserves the original datatypes:

Data = pd.concat([Data, Baseline[~Baseline.index.isin(Data.index)]])

Output:

>>> Data
   Phase  ENSO  EJO
0      1    -1  2.0
1      1     0  2.0
2      1     1  2.0
3      2    -1  7.0
4      2     1  1.0
5      2     1  0.0


问:
cumulative frequency column but resetting under a condition
I have a dataframe (on Python) with columns that contains the time and the number of products associated to an specific order.

I created a column that splits the time in intervals of 30 minutes (block of time) and then I counted the number of products on that specific Block of Time (using groupby).

Now I would like to add a cummulative frequency that restarts on every single block.

On this example, my new columns should be [2,3,3,5,7,...]

答:
The Cumulative Sum for each Block of Time within dataframe can be achieved by GroupBy.cumsum():

import pandas as pd
import numpy as np

df = pd.DataFrame({
         'N Products'       : [2, 1, 3, 5, 2],
         'Block of Time'    : ['12:30:00', '12:30:00', '13:30:00', '14:00:00', '14:00:00'],
         'Products on Block': [3, 3, 3, 7, 7],

})

print(df)
#   N Products    Block of Time      Products on Block
#0           2      12:30:00                  3
#1           1      12:30:00                  3
#2           3      13:30:00                  3
#3           5      14:00:00                  7
#4           2      14:00:00                  7
```
<p>Output:</p>
```df['Cumulative Products'] = df.groupby('Block of Time')['N Products'].cumsum()
print(df)
#    N Products   Block of Time      Products on Block   Cumulative Products
#0         2        12:30:00                  3                    2
#1         1        12:30:00                  3                    3
#2         3        13:30:00                  3                    3
#3         5        14:00:00                  7                    5
#4         2        14:00:00                  7                    7
```
<p>CDF Plot:</p>
```df['Cumulative Products'].hist(cumulative = True)
```

Body:
The Cumulative Sum for each Block of Time within dataframe can be achieved by GroupBy.cumsum():

import pandas as pd
import numpy as np

df = pd.DataFrame({
         'N Products'       : [2, 1, 3, 5, 2],
         'Block of Time'    : ['12:30:00', '12:30:00', '13:30:00', '14:00:00', '14:00:00'],
         'Products on Block': [3, 3, 3, 7, 7],

})

print(df)
#   N Products    Block of Time      Products on Block
#0           2      12:30:00                  3
#1           1      12:30:00                  3
#2           3      13:30:00                  3
#3           5      14:00:00                  7
#4           2      14:00:00                  7

Output:

df['Cumulative Products'] = df.groupby('Block of Time')['N Products'].cumsum()
print(df)
#    N Products   Block of Time      Products on Block   Cumulative Products
#0         2        12:30:00                  3                    2
#1         1        12:30:00                  3                    3
#2         3        13:30:00                  3                    3
#3         5        14:00:00                  7                    5
#4         2        14:00:00                  7                    7

CDF Plot:

df['Cumulative Products'].hist(cumulative = True)


问:
Inline element's absolute child position problem
I have an inline element with relative positioning and multiline content.
It also contains a child with an absolute positioning.
So i want to align this child to the right position of the parent element (a code snippet below).

But the lines have different length, and child element is aligned to a shorter one of the lines.

The first question is why this happening?
And the second one: is the any way to fix this problem?

.container {
  max-width: 150px;
  background: lightgray;
}

.parent {
  background: lightblue;
  position: relative;
}

.child {
  position: absolute;
  width: 20px;
  height: 10px;
  background: salmon;
  top: 0;
  bottom: 0;
  margin-top: auto;
  margin-bottom: auto;
  right:0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <span class="parent">
   Looooooooooooong Text here
   <div class="child"></div>
  </span>
</div></code>```

答:
It does not align to the shorter line, it aligns to the last line because it appears after that line in the HTML markup.

You can set the display mode of .parent to display: inline-block; in order to give it block boundaries, it makes more sense than positionning an element absoultely in relation to a normal inline layout.

Also, .child should be a  as well,
 is a block element and it is not valid to put it inside a  which is an inline element[1]. The browser is forgiving and letting it work but you should avoid such a situation.

[1] In HTML5 the terms "block element" and "inline element" was replaced with another model, but the prencip still applies

.container {
  max-width: 150px;
  background: lightgray;
}

.parent {
  background: lightblue;
  position: relative;
  display: inline-block;
}

.child {
  position: absolute;
  width: 20px;
  height: 10px;
  background: salmon;
  top: 0;
  bottom: 0;
  margin-top: auto;
  margin-bottom: auto;
  right:0;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="container">
  <span class="parent">
    Looooooooooooong Text Here
   <span class="child"></span>
  </span>
</div></code>```

Body:
I have an inline element with relative positioning and multiline content.
It also contains a child with an absolute positioning.
So i want to align this child to the right position of the parent element (a code snippet below).

But the lines have different length, and child element is aligned to a shorter one of the lines.

The first question is why this happening?
And the second one: is the any way to fix this problem?

.container {
  max-width: 150px;
  background: lightgray;
}

.parent {
  background: lightblue;
  position: relative;
}

.child {
  position: absolute;
  width: 20px;
  height: 10px;
  background: salmon;
  top: 0;
  bottom: 0;
  margin-top: auto;
  margin-bottom: auto;
  right:0;
}

   Looooooooooooong Text here

Body:
It does not align to the shorter line, it aligns to the last line because it appears after that line in the HTML markup.

You can set the display mode of .parent to display: inline-block; in order to give it block boundaries, it makes more sense than positionning an element absoultely in relation to a normal inline layout.

Also, .child should be a <span> as well, <div> is a block element and it is not valid to put it inside a <span> which is an inline element[1]. The browser is forgiving and letting it work but you should avoid such a situation.

[1] In HTML5 the terms "block element" and "inline element" was replaced with another model, but the prencip still applies

.container {
  max-width: 150px;
  background: lightgray;
}

.parent {
  background: lightblue;
  position: relative;
  display: inline-block;
}

.child {
  position: absolute;
  width: 20px;
  height: 10px;
  background: salmon;
  top: 0;
  bottom: 0;
  margin-top: auto;
  margin-bottom: auto;
  right:0;
}

<div class="container">
  <span class="parent">
    Looooooooooooong Text Here
   <span class="child"></span>
  </span>
</div>


问:
Parse HTML with jquery
suppose in a variable html is saved like

```<code>var vhtm="<div><div id='test'>zebra</div><div id='foo'>here is my many other html content</div></div>";
</code>```

i want to parse the above html stored in variable with the help of jquery.
i need to extract a particular div by id and including its content. the return result would like

```<code><div id='foo'>here is my many other html content</div>
</code>```

so i need to find div by id like id='foo'

please help me how to parse the above like jquery.

答: I don't know of any nice way to do that. I would set this as the HTML contents of an DOM element ($(document.createElement('div')).html(vhtm).find('#foo')) or create an about:blank iframe, add the HTML to it and use $(iframe.contentWindow.document.body).find(...) if it requires isolation from the page you're running the script on for some reason

Title: Parse HTML with jquery

Body:
suppose in a variable html is saved like

var vhtm="

zebra

here is my many other html content

";

i want to parse the above html stored in variable with the help of jquery.
i need to extract a particular div by id and including its content. the return result would like

here is my many other html content

so i need to find div by id like id='foo'

please help me how to parse the above like jquery.


问:
Javascript: using "!!" in boolean context
Is there any reason to use !!someValue (which is equivalent to Boolean(someValue)) in a boolean context? In other words, in situations like if (someValue) ..., does it make sense to write if (!!someValue) ...?

It hurts my eyes and I think it's redundant, but I want to verify that there aren't any edge cases that require it - because I came across a codebase where this seems to be the default way of checking for truthiness.

Clarification: yes, in the general case !!someValue will convert someValue to a boolean; I'm referring to contexts where the runtime will automatically convert someValue to true or false.

答:
Can't say I know why anyone would rely on directly checking booleans rather than on truthiness, but there is at least one scenario where truthiness is different than coercing with !!.

console.log([] == false); // true
console.log(!![] == false); // false
if([]) { console.log(true); } // true
if([] == false) { console.log(true); } // true
if(!![] == false) { console.log(true); } else { console.log(false); } // false```


问:
Docker and playwright
I need to install playwright inside of docker. This is my dockerfile.

```<code>FROM python:3.9

EXPOSE 8000

WORKDIR /fastanalytics

COPY /requirements.txt /fastanalytics/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /fastanalytics/requirements.txt

RUN playwright install
RUN playwright install-deps
RUN apt-get update && apt-get upgrade -y

</code>```

But when I am installing I got the below error. I tried installing everything in the error message but it didn't help.

```<code>E: Package 'ttf-ubuntu-font-family' has no installation candidate
E: Unable to locate package libenchant1c2a
E: Unable to locate package libicu66
E: Package 'libjpeg-turbo8' has no installation candidate
</code>```

答:
RUN apt-get update && playwright install-deps

While I have not used playwright, this seems to be a Docker issue. Playwright seems to be using apt-get to install the dependencies. In that case, you need to ensure apt-get update is run before playwright install-deps. While you can use two separate RUN statements to accomplish this, it is not advisable sinceapt-get update may not be run because of Docker's caching capabilities.

Title: Docker and playwright

Body:
I need to install playwright inside of docker. This is my dockerfile.

FROM python:3.9

EXPOSE 8000

WORKDIR /fastanalytics

COPY /requirements.txt /fastanalytics/requirements.txt

RUN pip install --no-cache-dir --upgrade -r /fastanalytics/requirements.txt

RUN playwright install
RUN playwright install-deps
RUN apt-get update && apt-get upgrade -y

But when I am installing I got the below error. I tried installing everything in the error message but it didn't help.

E: Package 'ttf-ubuntu-font-family' has no installation candidate
E: Unable to locate package libenchant1c2a
E: Unable to locate package libicu66
E: Package 'libjpeg-turbo8' has no installation candidate


问:
In C++, why is the subtraction result between iterators a long not other types?
Why is the subtraction result between iterators a long not other types?

For example:

```<code>vector<int> data{1, 2, 3, 4};
vector<int>::iterator curr = data.begin();

cout << typeid(curr - data.begin()).name();
</code>```

Gives:

```<code>l
</code>```

答:
In C++, why is the subtraction result between iterators a long not other types?

It is not necessarily long. It can be another signed integer type.

The standard library implementation that you use has chosen long. The type wasn't another type in your case because the standard library implementers didn't choose another type.

Body:
Why is the subtraction result between iterators a long not other types?

For example:

vector<int> data{1, 2, 3, 4};
vector<int>::iterator curr = data.begin();

cout << typeid(curr - data.begin()).name();

Gives:

l


答:
I side with @dangom on this one. You could restructure how you are passing the arguments to your function, or use Union instead.

```<code>from typing import List, Sequence, Union

def more_correct(ints: Sequence[int], flag: bool) -> List[int]:
    ...

def less_correct(xs: Sequence[Union[int, bool]]) -> List[int]:
    ...
</code>```

Title: Type hint for list with fixed start and end types but variable length

Body:
I side with @dangom on this one. You could restructure how you are passing the arguments to your function, or use Union instead.

from typing import List, Sequence, Union

def more_correct(ints: Sequence[int], flag: bool) -> List[int]:
    ...

def less_correct(xs: Sequence[Union[int, bool]]) -> List[int]:
    ...


问:
openxlsx::writeData() cut the column names of my dataset even if I force colNames=TRUE
I have several cities with stats stored into dataframes lists (each list have one dataframe for each city). I want to create an excel sheet with all the dataframes for each city. Each dataframe will be stored in a different tab.

This is my code :

```<code>pblapply(Communes$Commune, FUN=function(x) {
    message(sprintf("Commune de %s",x))
    xPath <- sprintf("output/%s/Fiche Communale %s.xlsx",x,x)
    fiche <- openxlsx::createWorkbook(sprintf("Fiche Communale %s",x))
    lapply(list_file$Tables, FUN=function(f) {
      xSheet=tools::file_path_sans_ext(f)
      openxlsx::addWorksheet(fiche,xSheet)
      openxlsx::writeData(fiche, xSheet, eval(parse(text = xSheet))[x], colNames=TRUE)
      openxlsx::saveWorkbook(fiche, xPath, overwrite = TRUE)
    })
  })
</code>```

I'm doing a lapply on the city names list (communes$commune) and then for each city I create the excel workbook with a sheet for each object name into list_files$Tables.

Even if I set colNames=TRUE (which is the default value) writeData() always remove the columns names.

I need my column names. Any idea why this happen, and how to avoid it ?

Thanks.

答:
Finally I fixed my issue using</p>
```<code>openxlsx::write.xlsx(DataCommune, xPath, row.names = FALSE, colWidths='auto')
</code>```

Body:
I have several cities with stats stored into dataframes lists (each list have one dataframe for each city). I want to create an excel sheet with all the dataframes for each city. Each dataframe will be stored in a different tab.

This is my code :

pblapply(Communes$Commune, FUN=function(x) {
    message(sprintf("Commune de %s",x))
    xPath <- sprintf("output/%s/Fiche Communale %s.xlsx",x,x)
    fiche <- openxlsx::createWorkbook(sprintf("Fiche Communale %s",x))
    lapply(list_file$Tables, FUN=function(f) {
      xSheet=tools::file_path_sans_ext(f)
      openxlsx::addWorksheet(fiche,xSheet)
      openxlsx::writeData(fiche, xSheet, eval(parse(text = xSheet))[x], colNames=TRUE)
      openxlsx::saveWorkbook(fiche, xPath, overwrite = TRUE)
    })
  })

I'm doing a lapply on the city names list (communes$commune) and then for each city I create the excel workbook with a sheet for each object name into list_files$Tables.

Even if I set colNames=TRUE (which is the default value) writeData() always remove the columns names.

I need my column names. Any idea why this happen, and how to avoid it ?

Thanks.

Body:
Finally I fixed my issue using

openxlsx::write.xlsx(DataCommune, xPath, row.names = FALSE, colWidths='auto')


问:
Library Database Design
Hi i've trying to design a library database.
Entities are

Book

Magazine

DVD

Member

Librarian

...

Media types can be borrowed by members.Should i create 3 different

loan tables for all media types or just one loan table.

if we think media as object , (book,magazine and dvd inherits

media ) how can they expressed in E&R diagram.

If all copies of a book are borrowed,the book can be    reservable.I
can control it programatically(using select count(*) from books)

but    i wonder if there is an efficient way to do this.

答:
I would have one loan table that refers to a media (assuming 2) that is much easier to get totals etc.

Basically what you want in code is an extend, the book, magazine and dvd are all media. This is modeled by having a book with a reference to a media. To make a differentiation and link at the media you could add a refId, which refers to the book, magazine and dvd. And a enum ('BOOK', 'MAGAZINE', 'DVD') that tells to which it refers.

Probably the only moment you want to show this information is when you are checking out or information about the book is queried any way.

Title: Library Database Design


问:
Function callback to change text color (just for one) | Flutter
I'm trying to create a SideMenu with different SideMenuItems.
For that I created a new class and want to update the color of Text when the SideMenuItem is clicked. For that I want to transfer the activeState and all that stuff you see in the code below:

The use of my class in the Widget:

```<code>bool isActive = false;
...
            SideMenuItem(
              icon: Icon(
                Icons.inbox,
                size: 20,
                color: isActive ? kPrimaryColor : kGrayColor,
              ),
              activeState: isActive,
              title: "Archiv",
              toggleActiveState: (activeState) {
                setState(() {
                  isActive = !activeState;
                });
              },
            ),
</code>```

And here is my class:

```<code>import 'package:flutter/material.dart';
import 'package:gastronomy/constants.dart';

class SideMenuItem extends StatelessWidget {
  // ignore: prefer_const_constructors_in_immutables
  SideMenuItem({
    Key? key,
    required this.activeState,
    this.itemCount = 0,
    this.showBorder = true,
    @required this.icon,
    @required this.title,
    required this.toggleActiveState,
  }) : super(key: key);

  final bool activeState;
  final bool showBorder;
  final int itemCount;
  final Icon? icon;
  final String? title;
  final Function(bool) toggleActiveState;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: kDefaultPadding),
      child: InkWell(
        onTap: () {
          toggleActiveState(activeState);
        },
        child: Row(
          children: [
            const SizedBox(width: 15),
            const SizedBox(width: kDefaultPadding / 4),
            Expanded(
              child: Container(
                padding: const EdgeInsets.only(bottom: 15, right: 5),
                decoration: showBorder
                    ? const BoxDecoration(
                        border: Border(
                          bottom: BorderSide(color: Color(0xFFDFE2EF)),
                        ),
                      )
                    : null,
                child: Row(
                  children: [
                    icon!,
                    const SizedBox(width: kDefaultPadding * 0.75),
                    Text(
                      title!,
                      style: Theme.of(context).textTheme.button?.copyWith(
                            color: activeState ? kTextColor : kGrayColor,
                          ),
                    ),
                    const Spacer(),
                    // if (itemCount != null) CounterBadge(count: itemCount)
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
</code>```

I ended up with that pieces of code but well, how you might know, all SideMenuItems change there color when I click one.
I'm pretty new at using this way of code so I would be thankful to all informations you can include into your answer.

答:
One option is to render all the menu items through a map function and compare each item with the selected option, like in the example below:

import 'package:flutter/material.dart';

class MenuExample extends StatefulWidget {
  const MenuExample({Key? key}) : super(key: key);

  @override
  _MenuExampleState createState() => _MenuExampleState();
}

class _MenuExampleState extends State<MenuExample> {
  List<String> menuOptions = const ['Item 1', 'Item 2', 'Item 3'];

  String selectedOption = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        backgroundColor: Colors.amber,
        child: ListView(
            children: menuOptions.map((menuOption) {
          return InkWell(
            onTap: () => setState(() {
              selectedOption = menuOption;
            }),
            child: MenuItem(
              name: menuOption,
              isSelected: menuOption == selectedOption,
            ),
          );
        }).toList()),
      ),
    );
  }
}

class MenuItem extends StatelessWidget {
  const MenuItem({Key? key, this.isSelected = false, required this.name})
      : super(key: key);

  final bool isSelected;
  final String name;

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(
        name,
        style: TextStyle(
            fontWeight: isSelected ? FontWeight.bold : FontWeight.normal),
      ),
    );
  }
}

```

Body:
I'm trying to create a SideMenu with different SideMenuItems.
For that I created a new class and want to update the color of Text when the SideMenuItem is clicked. For that I want to transfer the activeState and all that stuff you see in the code below:

The use of my class in the Widget:

bool isActive = false;
...
            SideMenuItem(
              icon: Icon(
                Icons.inbox,
                size: 20,
                color: isActive ? kPrimaryColor : kGrayColor,
              ),
              activeState: isActive,
              title: "Archiv",
              toggleActiveState: (activeState) {
                setState(() {
                  isActive = !activeState;
                });
              },
            ),

And here is my class:

import 'package:flutter/material.dart';
import 'package:gastronomy/constants.dart';

class SideMenuItem extends StatelessWidget {
  // ignore: prefer_const_constructors_in_immutables
  SideMenuItem({
    Key? key,
    required this.activeState,
    this.itemCount = 0,
    this.showBorder = true,
    @required this.icon,
    @required this.title,
    required this.toggleActiveState,
  }) : super(key: key);

  final bool activeState;
  final bool showBorder;
  final int itemCount;
  final Icon? icon;
  final String? title;
  final Function(bool) toggleActiveState;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(top: kDefaultPadding),
      child: InkWell(
        onTap: () {
          toggleActiveState(activeState);
        },
        child: Row(
          children: [
            const SizedBox(width: 15),
            const SizedBox(width: kDefaultPadding / 4),
            Expanded(
              child: Container(
                padding: const EdgeInsets.only(bottom: 15, right: 5),
                decoration: showBorder
                    ? const BoxDecoration(
                        border: Border(
                          bottom: BorderSide(color: Color(0xFFDFE2EF)),
                        ),
                      )
                    : null,
                child: Row(
                  children: [
                    icon!,
                    const SizedBox(width: kDefaultPadding * 0.75),
                    Text(
                      title!,
                      style: Theme.of(context).textTheme.button?.copyWith(
                            color: activeState ? kTextColor : kGrayColor,
                          ),
                    ),
                    const Spacer(),
                    // if (itemCount != null) CounterBadge(count: itemCount)
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

I ended up with that pieces of code but well, how you might know, all SideMenuItems change there color when I click one.
I'm pretty new at using this way of code so I would be thankful to all informations you can include into your answer.


问:
How to filter in the table (so that they end up at the bottom of the table) the elements that belong to the "Film" section
I have a set of elements. Some of these are part of section "Film", others of section "Video" and still others of section "VideoYoutube". There is a special column that defines this Section.

The elements in the table that are part of section "Film" must be placed at the bottom of the table.

To be able to put the elements at the bottom of the table I know that you have to use the command:

insertRow(-1);

Since my table is dynamic, how can I set what I want?

Items.forEach(function (item) {
                    let child = document.createElement("tr");
                    child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`;
                    table.appendChild(child);
                })```
<pre class="snippet-code-html lang-html prettyprint-override"><code>    <table id="my-table" width="90%">
            <tr>
                <th>Id</th>
                <th>Title</th>
                <th>Image</th>
                <th>Section</th>
                <th>Date</th>
            </tr>

        </table></code>```

To understand better, I have to filter by Film only

Example to understand

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}]
itemarr.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="my-table" width="90%">
  <tr>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table></code>```

答:
Maybe try this one by pushing the one you want showing later to another array ?

Of course not the best solution, but easiest solution.

If you simply want to use insertRow(-1), you will facing the problem of inserting item in front of the section part th>Id	 Title	 Image	 Section	 Date	, so the easiest way will using this

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}];
let lateradd = []

itemarr.forEach(function(item) {

let child = document.querySelector('table').insertRow(-1);
if(item.section ==="Video"){
child.innerHTML = `
   ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}
`;
}else{lateradd.push(item)}
})
if(lateradd){
lateradd.forEach(function(i){
document.querySelector('table').insertRow(-1).innerHTML =`
   ${i.id}
                    ${i.title}
                    ${i.image}
                    ${i.section}
                    ${i.date}
`
})

}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><table id="my-table" width="90%">
  <tr id='section'>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table></code>```

Body:
I have a set of elements. Some of these are part of section "Film", others of section "Video" and still others of section "VideoYoutube". There is a special column that defines this Section.

The elements in the table that are part of section "Film" must be placed at the bottom of the table.

To be able to put the elements at the bottom of the table I know that you have to use the command:

insertRow(-1);

Since my table is dynamic, how can I set what I want?

Items.forEach(function (item) {
                    let child = document.createElement("tr");
                    child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`;
                    table.appendChild(child);
                })

                Id
                Title
                Image
                Section
                Date

To understand better, I have to filter by Film only

Example to understand

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}]
itemarr.forEach(function(item) {
  let child = document.querySelector('table').insertRow(-1)
  child.innerHTML = `
                    ${item.id}
                    ${item.title}
                    ${item.image}
                    ${item.section}
                    ${item.date}	`

})

    Id
    Title
    Image
    Section
    Date

Body:
Maybe try this one by pushing the one you want showing later to another array ?

Of course not the best solution, but easiest solution.

If you simply want to use insertRow(-1), you will facing the problem of inserting item in front of the section part th>Id</th> <th>Title</th> <th>Image</th> <th>Section</th> <th>Date</th>, so the easiest way will using this

let itemarr = [{
  id: 1,
  title: "image 1",
  image: "url 1",
  section: "Film",
  date: "date 1",
}, {
  id: 2,
  title: "image 2",
  image: "url 2",
  section: "Video",
  date: "date 2",
},
{
  id: 3,
  title: "image 3",
  image: "url 2",
  section: "Film",
  date: "date 2",
},
{
  id: 4,
  title: "image 4",
  image: "url 2",
  section: "Video",
  date: "date 2",
}];
let lateradd = []

itemarr.forEach(function(item) {

let child = document.querySelector('table').insertRow(-1);
if(item.section ==="Video"){
child.innerHTML = `
   <td>${item.id}</td>
                    <td>${item.title}</td>
                    <td>${item.image}</td>
                    <td>${item.section}</td>
                    <td>${item.date}</td>
`;
}else{lateradd.push(item)}
})
if(lateradd){
lateradd.forEach(function(i){
document.querySelector('table').insertRow(-1).innerHTML =`
   <td>${i.id}</td>
                    <td>${i.title}</td>
                    <td>${i.image}</td>
                    <td>${i.section}</td>
                    <td>${i.date}</td>
`
})

}

<table id="my-table" width="90%">
  <tr id='section'>
    <th>Id</th>
    <th>Title</th>
    <th>Image</th>
    <th>Section</th>
    <th>Date</th>
  </tr>

</table>