问:
fire ajax call only if the form validates
I am using bootstrap form validator script for my form which is being submitted through ajax.
The problem is even if validation fails the script gets submitted

this is validation code

```<code>(function() {
  'use strict';
  window.addEventListener('load', function() {
      // Get the forms we want to add validation styles to
      var forms = document.getElementsByClassName('needs-validation');
      // Loop over them and prevent submission
      var validation = Array.prototype.filter.call(forms, function(form) {
          form.addEventListener('submit', function(event) {
              if (form.checkValidity() === false) {
                  event.preventDefault();
                  event.stopPropagation();
              }
              form.classList.add('was-validated');
          }, false);
      });
  }, false);
})();
</code>```

If I place a function below this to execute ajax call that submits the form it submits even if form isn't validated.

this is the form code

```<code><div class="form-group text-white needs-validation" novalidate>

        <form method="POST" id="rform" action="javascript:return">
</code>```

答:
You missed the adding the class needs-validation that your Javascript code needs and novalidate

<form method="POST" id="rform" action="" novalidate class="needs-validation">
  Name: <input type="text" name="name" required>

   ID: <input type="text" name="registration_id" min="3">

  <input type="submit" name="submit">
</form>

```

Body:
I am using bootstrap form validator script for my form which is being submitted through ajax.
The problem is even if validation fails the script gets submitted

this is validation code

(function() {
  'use strict';
  window.addEventListener('load', function() {
      // Get the forms we want to add validation styles to
      var forms = document.getElementsByClassName('needs-validation');
      // Loop over them and prevent submission
      var validation = Array.prototype.filter.call(forms, function(form) {
          form.addEventListener('submit', function(event) {
              if (form.checkValidity() === false) {
                  event.preventDefault();
                  event.stopPropagation();
              }
              form.classList.add('was-validated');
          }, false);
      });
  }, false);
})();

If I place a function below this to execute ajax call that submits the form it submits even if form isn't validated.

this is the form code

        <form method="POST" id="rform" action="javascript:return">

Body:
You missed the adding the class needs-validation that your Javascript code needs and novalidate

<form method="POST" id="rform" action="" novalidate class="needs-validation">
  Name: <input type="text" name="name" required> <br>
   ID: <input type="text" name="registration_id" min="3"> <br>
  <input type="submit" name="submit">
</form>

<script>
  (function() {
    'use strict';
    window.addEventListener('load', function() {
      // Get the forms we want to add validation styles to
      var forms = document.getElementsByClassName('needs-validation');
      // Loop over them and prevent submission
      var validation = Array.prototype.filter.call(forms, function(form) {
        form.addEventListener('submit', function(event) {
          if (form.checkValidity() === false) {
            event.preventDefault();
            event.stopPropagation();
          }
          form.classList.add('was-validated');
        }, false);
      });
    }, false);
  })();
</script>


来源: stackexchange

问:
Comparing boxed value types
Today I stumbled upon an interesting bug I wrote. I have a set of properties which can be set through a general setter. These properties can be value types or reference types.

```<code>public void SetValue( TEnum property, object value )
{
    if ( _properties[ property ] != value )
    {
        // Only come here when the new value is different.
    }
}
</code>```

When writing a unit test for this method I found out the condition is always true for value types. It didn't take me long to figure out this is due to boxing/unboxing. It didn't take me long either to adjust the code to the following:

```<code>public void SetValue( TEnum property, object value )
{
    if ( !_properties[ property ].Equals( value ) )
    {
        // Only come here when the new value is different.
    }
}
</code>```

The thing is I'm not entirely satisfied with this solution. I'd like to keep a simple reference comparison, unless the value is boxed.

The current solution I am thinking of is only calling Equals() for boxed values. Doing a check for a boxed values seems a bit overkill. Isn't there an easier way?

答:
If you need different behaviour when you're dealing with a value-type then you're obviously going to need to perform some kind of test. You don't need an explicit check for boxed value-types, since all value-types will be boxed** due to the parameter being typed as object.

This code should meet your stated criteria: If value is a (boxed) value-type then call the polymorphic Equals method, otherwise use == to test for reference equality.

```<code>public void SetValue(TEnum property, object value)
{
    bool equal = ((value != null) && value.GetType().IsValueType)
                     ? value.Equals(_properties[property])
                     : (value == _properties[property]);

    if (!equal)
    {
        // Only come here when the new value is different.
    }
}
</code>```

( ** And, yes, I know that Nullable<T> is a value-type with its own special rules relating to boxing and unboxing, but that's pretty much irrelevant here.)

ContentLicense: CC BY-SA 3.0

Title: Comparing boxed value types

Body:
Today I stumbled upon an interesting bug I wrote. I have a set of properties which can be set through a general setter. These properties can be value types or reference types.

public void SetValue( TEnum property, object value )
{
    if ( _properties[ property ] != value )
    {
        // Only come here when the new value is different.
    }
}

When writing a unit test for this method I found out the condition is always true for value types. It didn't take me long to figure out this is due to boxing/unboxing. It didn't take me long either to adjust the code to the following:

public void SetValue( TEnum property, object value )
{
    if ( !_properties[ property ].Equals( value ) )
    {
        // Only come here when the new value is different.
    }
}

The thing is I'm not entirely satisfied with this solution. I'd like to keep a simple reference comparison, unless the value is boxed.

The current solution I am thinking of is only calling Equals() for boxed values. Doing a check for a boxed values seems a bit overkill. Isn't there an easier way?

Body:
If you need different behaviour when you're dealing with a value-type then you're obviously going to need to perform some kind of test. You don't need an explicit check for boxed value-types, since all value-types will be boxed** due to the parameter being typed as object.

This code should meet your stated criteria: If value is a (boxed) value-type then call the polymorphic Equals method, otherwise use == to test for reference equality.

public void SetValue(TEnum property, object value)
{
    bool equal = ((value != null) && value.GetType().IsValueType)
                     ? value.Equals(_properties[property])
                     : (value == _properties[property]);

    if (!equal)
    {
        // Only come here when the new value is different.
    }
}

( ** And, yes, I know that Nullable<T> is a value-type with its own special rules relating to boxing and unboxing, but that's pretty much irrelevant here.)


问:
componentWillMount for react functional component?
For react class component, we have the componentWillMount() lifecycle method, where we can perform tasks before loading the component. Tasks like, a call to backend and use the response to show that data in that frontend.

What if I want the same thing in a functional component? Like I have used react chartJS and for that the data values I want to be retrieved from backend response, and then the chart will populate based on those datas.

答:
componentWillMount is call only one time before initial render.
I make a sample code, check it out below

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [mounted, setMounted] = useState(false)

  if(!mounted){
    // Code for componentWillMount here
    // This code is called only one time before intial render
  }

  useEffect(() =>{
    setMounted(true)
  },[])

  return (

  );
}```
</div>
</div>
</p>

<ul>
<li>As you mentioned you want to make an api call, it usually happen in <code>componentDidmount</code> and you can simply use <code>useEffect</code> hook with empty array as dependencies in functional component</li>
</ul>

<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [mounted, setMounted] = useState(false)

  useEffect(() =>{
    // This is similar to componentDidMount
    // Call back-end api here
  },[])

  return (
    <div className="App">

    </div>
  );
}</code>```

ContentLicense: CC BY-SA 4.0

Body:
componentWillMount is call only one time before initial render.
I make a sample code, check it out below

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [mounted, setMounted] = useState(false)

  if(!mounted){
    // Code for componentWillMount here
    // This code is called only one time before intial render
  }

  useEffect(() =>{
    setMounted(true)
  },[])

  return (
    <div className="App">

    </div>
  );
}

As you mentioned you want to make an api call, it usually happen in componentDidmount and you can simply use useEffect hook with empty array as dependencies in functional component

import React, { useState, useEffect } from "react";
import "./styles.css";

export default function App() {
  const [mounted, setMounted] = useState(false)

  useEffect(() =>{
    // This is similar to componentDidMount
    // Call back-end api here
  },[])

  return (
    <div className="App">

    </div>
  );
}


问:
how and where to add a more specific join of two entity tables
I am trying to build what i thought to be an easy directory for our company. I'm not a web developer, I am a standalone application developer, so my knowledge of ASP.NET MVC and Entity Framework is limited.

I followed some instructions I found online and created the entities (2 tables) in an older application, the SQL statements used to get the list of employees utilizes a left outer join and 3 where parameters. I'm assuming I have to use LINQ in the model.Context.vb file?

I also see Details methods in the controller but it creates an instance of this context file so I assume that is where I need to combine the two entities and then access the refined list through the controller, is this about right? How and where would I write the LINQ statement if that's what I even need to do?

This is the controller:

```<code>Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Entity
Imports System.Linq
Imports System.Net
Imports System.Web
Imports System.Web.Mvc
Imports MillDirectory

Namespace Controllers
Public Class tblUsersController
    Inherits System.Web.Mvc.Controller

    Private db As New HDDataEntities

    ' GET: tblUsers
    Function Index() As ActionResult
        Return View(db.tblUsers.ToList())
    End Function

    ' GET: tblUsers/Details/5
    Function Details(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Create
    Function Create() As ActionResult
        Return View()
    End Function

    ' POST: tblUsers/Create
    'To protect from overposting attacks, please enable the specific properties you want to bind to, for
    'more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Function Create(<Bind(Include:="USLanID,USAS400ID,USVaxID,USLName,USFname,USDepartment,USPhoneNumber,USFaxNumber,USExtension,USPagerNumber,USSupervisor,USPhoneAreaCode,USPagerAreaCode,USFaxAreaCode,USHelpDeskFlag,USAvailable,USAvailableDate,USEmail,USDomain,USInactive,KICKUser,KICKMinutes,USNewTicketNotify,USNAME,USClosedTicketnotify,USCellAreaCode,USCellPhoneNumber,USAllowedToPage,USLocation,USHomeArea,USHomePhone,USExcludeHomePhone,USEmpNum,USCellTxtMsgAddress,USHireDate,USTrackVac,USIncludeinCellDownload,USRecoveryMsg,USPowerMsg,USPMBreakMsg,USProdRPT,USStockRPT,USPagingType,USPicturePath,USTest,USPMBreakMins,USPMBreakNum,USmsgPCName")> ByVal tblUser As tblUser) As ActionResult
        If ModelState.IsValid Then
            db.tblUsers.Add(tblUser)
            db.SaveChanges()
            Return RedirectToAction("Index")
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Edit/5
    Function Edit(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' POST: tblUsers/Edit/5
    'To protect from overposting attacks, please enable the specific properties you want to bind to, for
    'more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Function Edit(<Bind(Include:="USLanID,USAS400ID,USVaxID,USLName,USFname,USDepartment,USPhoneNumber,USFaxNumber,USExtension,USPagerNumber,USSupervisor,USPhoneAreaCode,USPagerAreaCode,USFaxAreaCode,USHelpDeskFlag,USAvailable,USAvailableDate,USEmail,USDomain,USInactive,KICKUser,KICKMinutes,USNewTicketNotify,USNAME,USClosedTicketnotify,USCellAreaCode,USCellPhoneNumber,USAllowedToPage,USLocation,USHomeArea,USHomePhone,USExcludeHomePhone,USEmpNum,USCellTxtMsgAddress,USHireDate,USTrackVac,USIncludeinCellDownload,USRecoveryMsg,USPowerMsg,USPMBreakMsg,USProdRPT,USStockRPT,USPagingType,USPicturePath,USTest,USPMBreakMins,USPMBreakNum,USmsgPCName")> ByVal tblUser As tblUser) As ActionResult
        If ModelState.IsValid Then
            db.Entry(tblUser).State = EntityState.Modified
            db.SaveChanges()
            Return RedirectToAction("Index")
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Delete/5
    Function Delete(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' POST: tblUsers/Delete/5
    <HttpPost()>
    <ActionName("Delete")>
    <ValidateAntiForgeryToken()>
    Function DeleteConfirmed(ByVal id As String) As ActionResult
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        db.tblUsers.Remove(tblUser)
        db.SaveChanges()
        Return RedirectToAction("Index")
    End Function

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If (disposing) Then
            db.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub
End Class
End Namespace
</code>```

答:
Method 1: You can pull the result set by adding this in the Controller. I have edited the Index action:

```<code>Function Index() As ActionResult
    var query = from u in db.tblUser
                join p in db.tblUserPermission on u.UserID equals p.UserID
                where u.YourProperty == YourCondition
                into gj
                from x in gj.DefaultIfEmpty()
                select new {
                 UserID = u.UsergroupID,
                 UserPermission = p.UserPermission
                };
    Return View(query)
End Function
</code>```

Method 2:

```<code>Function Index() As ActionResult
    Return View(db.UserDbSet.UserPermissionList.Where(w => w.YourProperty ==
                w.YourFirstCond && w.YourAnotherProp == w.YourSecondCond).ToList())
End Function
</code>```

Assuming your DbSet for the left table is UserDbSet.
Before that, you would need to change the Models(Entities) as per your relation. I have given scenario of one to many relation.

```<code>//In tblUser Model
public List<tblUserPermission> UserPermissionList {get;set;}

//In tblUserPermission model
public tblUser User {get;set;}
</code>```

Sorry, models and first method are in C# code.

Body:
I am trying to build what i thought to be an easy directory for our company. I'm not a web developer, I am a standalone application developer, so my knowledge of ASP.NET MVC and Entity Framework is limited.

I followed some instructions I found online and created the entities (2 tables) in an older application, the SQL statements used to get the list of employees utilizes a left outer join and 3 where parameters. I'm assuming I have to use LINQ in the model.Context.vb file?

I also see Details methods in the controller but it creates an instance of this context file so I assume that is where I need to combine the two entities and then access the refined list through the controller, is this about right? How and where would I write the LINQ statement if that's what I even need to do?

This is the controller:

Imports System
Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Entity
Imports System.Linq
Imports System.Net
Imports System.Web
Imports System.Web.Mvc
Imports MillDirectory

Namespace Controllers
Public Class tblUsersController
    Inherits System.Web.Mvc.Controller

    Private db As New HDDataEntities

    ' GET: tblUsers
    Function Index() As ActionResult
        Return View(db.tblUsers.ToList())
    End Function

    ' GET: tblUsers/Details/5
    Function Details(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Create
    Function Create() As ActionResult
        Return View()
    End Function

    ' POST: tblUsers/Create
    'To protect from overposting attacks, please enable the specific properties you want to bind to, for
    'more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Function Create(<Bind(Include:="USLanID,USAS400ID,USVaxID,USLName,USFname,USDepartment,USPhoneNumber,USFaxNumber,USExtension,USPagerNumber,USSupervisor,USPhoneAreaCode,USPagerAreaCode,USFaxAreaCode,USHelpDeskFlag,USAvailable,USAvailableDate,USEmail,USDomain,USInactive,KICKUser,KICKMinutes,USNewTicketNotify,USNAME,USClosedTicketnotify,USCellAreaCode,USCellPhoneNumber,USAllowedToPage,USLocation,USHomeArea,USHomePhone,USExcludeHomePhone,USEmpNum,USCellTxtMsgAddress,USHireDate,USTrackVac,USIncludeinCellDownload,USRecoveryMsg,USPowerMsg,USPMBreakMsg,USProdRPT,USStockRPT,USPagingType,USPicturePath,USTest,USPMBreakMins,USPMBreakNum,USmsgPCName")> ByVal tblUser As tblUser) As ActionResult
        If ModelState.IsValid Then
            db.tblUsers.Add(tblUser)
            db.SaveChanges()
            Return RedirectToAction("Index")
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Edit/5
    Function Edit(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' POST: tblUsers/Edit/5
    'To protect from overposting attacks, please enable the specific properties you want to bind to, for
    'more details see https://go.microsoft.com/fwlink/?LinkId=317598.
    <HttpPost()>
    <ValidateAntiForgeryToken()>
    Function Edit(<Bind(Include:="USLanID,USAS400ID,USVaxID,USLName,USFname,USDepartment,USPhoneNumber,USFaxNumber,USExtension,USPagerNumber,USSupervisor,USPhoneAreaCode,USPagerAreaCode,USFaxAreaCode,USHelpDeskFlag,USAvailable,USAvailableDate,USEmail,USDomain,USInactive,KICKUser,KICKMinutes,USNewTicketNotify,USNAME,USClosedTicketnotify,USCellAreaCode,USCellPhoneNumber,USAllowedToPage,USLocation,USHomeArea,USHomePhone,USExcludeHomePhone,USEmpNum,USCellTxtMsgAddress,USHireDate,USTrackVac,USIncludeinCellDownload,USRecoveryMsg,USPowerMsg,USPMBreakMsg,USProdRPT,USStockRPT,USPagingType,USPicturePath,USTest,USPMBreakMins,USPMBreakNum,USmsgPCName")> ByVal tblUser As tblUser) As ActionResult
        If ModelState.IsValid Then
            db.Entry(tblUser).State = EntityState.Modified
            db.SaveChanges()
            Return RedirectToAction("Index")
        End If
        Return View(tblUser)
    End Function

    ' GET: tblUsers/Delete/5
    Function Delete(ByVal id As String) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        If IsNothing(tblUser) Then
            Return HttpNotFound()
        End If
        Return View(tblUser)
    End Function

    ' POST: tblUsers/Delete/5
    <HttpPost()>
    <ActionName("Delete")>
    <ValidateAntiForgeryToken()>
    Function DeleteConfirmed(ByVal id As String) As ActionResult
        Dim tblUser As tblUser = db.tblUsers.Find(id)
        db.tblUsers.Remove(tblUser)
        db.SaveChanges()
        Return RedirectToAction("Index")
    End Function

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        If (disposing) Then
            db.Dispose()
        End If
        MyBase.Dispose(disposing)
    End Sub
End Class
End Namespace

Body:
Method 1: You can pull the result set by adding this in the Controller. I have edited the Index action:

Function Index() As ActionResult
    var query = from u in db.tblUser
                join p in db.tblUserPermission on u.UserID equals p.UserID
                where u.YourProperty == YourCondition
                into gj
                from x in gj.DefaultIfEmpty()
                select new {
                 UserID = u.UsergroupID,
                 UserPermission = p.UserPermission
                };
    Return View(query)
End Function

Method 2:

Function Index() As ActionResult
    Return View(db.UserDbSet.UserPermissionList.Where(w => w.YourProperty ==
                w.YourFirstCond && w.YourAnotherProp == w.YourSecondCond).ToList())
End Function

Assuming your DbSet for the left table is UserDbSet.
Before that, you would need to change the Models(Entities) as per your relation. I have given scenario of one to many relation.

//In tblUser Model
public List<tblUserPermission> UserPermissionList {get;set;}

//In tblUserPermission model
public tblUser User {get;set;}

Sorry, models and first method are in C# code.


问:
Which is faster? Query to a local table, or a programmed value list in a combobox control
I have a series of combo boxes on a form - and I have connected them to lists of data in the past by using a pass-through query to a sql server, and while this performs well in most cases, many of my users have been accessing the database using a VPN, and the response to populate them seems slow.

I started programming the system to populate a local table from the pass through query on form load - then, used a local query to show results in the proper order.  Once they select the first combo box the second combobox filters from there, to the third, and the fourth (in some cases I have more than 4 too),

All of this is intended so I don't have to connect to the server each time they change selections.  However, I am thinking that having a value list that is hard coded might be faster in performance for the lists that don't change - such as the highest level in the selection hiearchy (think of 3 or 4 comboboxes that effect each other and filter the next ones results).

Does anyone know if using a hardcoded value list in a combobox has a performance gain over a local query to a local table in MS Access?  I am using MS Access 2016 if it helps.

答:
Ok, a few things: you do NOT want to use a pass-through query for a listbox/combo box. NEVER!!!!

Why? The Access client cannot filter a PT query. This seems contradictory here.

First, lets be clear: the fastest way to pull data is a PT query - hands down.

However lets assume the combo box is large - say 3000 rows.

AND ALSO assume the combo box is bound (that means it saves a value to the form's bound recordset.

Well, remember the above rule!!! - Access client NEVER is able to filter the PT query.

So, if you have a report that you run? If your PT query is not PRE-FILTERED (the criteria exists in the PT query - even a stored procedure), then adding a where clause to the form (or report), or in this case a combo box WILL NOT WORK - the FULL data set is returned and can not be filtered.

So, if you have a PT query with 500,000 rows, and you do this:

```<code>docmd.OpenReport "rtpInvoice", acViewPreview,,"InvoiceNumber = 1234"
</code>```

The above will pull 500,000 rows.

However, if you used a plane jane linked table, or best link to a view, and it ALSO has 500,000 rows? Well only 1 record comes down the network pipe!

So, if that combo box is bound to 5000 rows, and a simple navigation to the NEXT record occurs? Well, the combo box will of course have a single value - the underlying recordset of the bound form. But, it cannot filter + display the ONE value for the combo box (most combo boxes are multi-column - 1st column = PK, and 2nd column = some kind of description.

So, access is actually quite smart, and it will attempt to ONLY pulls the ONE value from the 5000 rows driving the combo box. But the exception to the rule is of course a PT query!

Again: Access client cannot filter a PT query.

So, if the combo box has a large data set AND ALSO is feed by a PT query, then things run slow as a dog. I had one system in which the PT query was returning about 100,000 rows. Just a simple navigation to the next record was slow as a dog.

Replacing the PT query with a linked view made the form work near instant. This is because out of the 100,000 rows, Access is able to ONLY pull the ONE row for display of the combo box and that 2nd column.

So, while a PT query is the fastest way to pull data? Yes, 100% true, but you ONLY want to use that speed advantage WHEN you need ALL OF the records of that PT query. If you going to filter AFTER or AGAINST the PT query (such as is done for a bound combo box), then a full scan of all records driving that combo box will occur.

The best approach? Dump the  PT queries for a combo box, and replace them with linked views. You can even specify a sort in the view (yes, it does shove in the top 100%). So ONLY place the view name in the combo box - don't fire up the query builder.

And, you can even get away using a direct link to a linked table. Again, Access client can filter that data set for the combo box.

So, there is no need to waste all that developer time building a PT query for a combo box and there is no need (nor advantage in speed) attempting to use code to load up and fill a combo box. But, if the PT query is going to return more than about 30 rows, then you  want to dump the PT query and use a linked table, or even better is a linked view.

I would not mess around with pulling a table from server to local - you could do that, but that's just extra code, extra pain, and it really gains you very little. And often it can make things worse. Why pull a whole table of lots of rows for a combo box, when just launching the form, access is smart enough to ONLY pull the one row required for display of the combo box. It will not pull the data until you click on the combo to make a choice.

If your PT queries are say over 50 or 100 rows to fill the combo box, and that combo box i a bound combo box? Then you have to dump the PT query, and use a linked table/view - and you get much better performance.

Body:
Ok, a few things: you do NOT want to use a pass-through query for a listbox/combo box. NEVER!!!!

Why? The Access client cannot filter a PT query. This seems contradictory here.

First, lets be clear: the fastest way to pull data is a PT query - hands down.

However lets assume the combo box is large - say 3000 rows.

AND ALSO assume the combo box is bound (that means it saves a value to the form's bound recordset.

Well, remember the above rule!!! - Access client NEVER is able to filter the PT query.

So, if you have a report that you run? If your PT query is not PRE-FILTERED (the criteria exists in the PT query - even a stored procedure), then adding a where clause to the form (or report), or in this case a combo box WILL NOT WORK - the FULL data set is returned and can not be filtered.

So, if you have a PT query with 500,000 rows, and you do this:

docmd.OpenReport "rtpInvoice", acViewPreview,,"InvoiceNumber = 1234"

The above will pull 500,000 rows.

However, if you used a plane jane linked table, or best link to a view, and it ALSO has 500,000 rows? Well only 1 record comes down the network pipe!

So, if that combo box is bound to 5000 rows, and a simple navigation to the NEXT record occurs? Well, the combo box will of course have a single value - the underlying recordset of the bound form. But, it cannot filter + display the ONE value for the combo box (most combo boxes are multi-column - 1st column = PK, and 2nd column = some kind of description.

So, access is actually quite smart, and it will attempt to ONLY pulls the ONE value from the 5000 rows driving the combo box. But the exception to the rule is of course a PT query!

Again: Access client cannot filter a PT query.

So, if the combo box has a large data set AND ALSO is feed by a PT query, then things run slow as a dog. I had one system in which the PT query was returning about 100,000 rows. Just a simple navigation to the next record was slow as a dog.

Replacing the PT query with a linked view made the form work near instant. This is because out of the 100,000 rows, Access is able to ONLY pull the ONE row for display of the combo box and that 2nd column.

So, while a PT query is the fastest way to pull data? Yes, 100% true, but you ONLY want to use that speed advantage WHEN you need ALL OF the records of that PT query. If you going to filter AFTER or AGAINST the PT query (such as is done for a bound combo box), then a full scan of all records driving that combo box will occur.

The best approach? Dump the  PT queries for a combo box, and replace them with linked views. You can even specify a sort in the view (yes, it does shove in the top 100%). So ONLY place the view name in the combo box - don't fire up the query builder.

And, you can even get away using a direct link to a linked table. Again, Access client can filter that data set for the combo box.

So, there is no need to waste all that developer time building a PT query for a combo box and there is no need (nor advantage in speed) attempting to use code to load up and fill a combo box. But, if the PT query is going to return more than about 30 rows, then you  want to dump the PT query and use a linked table, or even better is a linked view.

I would not mess around with pulling a table from server to local - you could do that, but that's just extra code, extra pain, and it really gains you very little. And often it can make things worse. Why pull a whole table of lots of rows for a combo box, when just launching the form, access is smart enough to ONLY pull the one row required for display of the combo box. It will not pull the data until you click on the combo to make a choice.

If your PT queries are say over 50 or 100 rows to fill the combo box, and that combo box i a bound combo box? Then you have to dump the PT query, and use a linked table/view - and you get much better performance.


问:
Python - nested lists vs multiple dictionaries for bicycle gear calculator
this is my first Stack Overflow question so if this is not optimal please let me know, I appreciate the feedback.

I am studying Computer Science and for my final project I'm making a bicycle gear calculator. I want there to be 3 drop down menus (Brand and 1x or 2x, Crank, Cassette), the first menu (Brand) should auto-populate the next 2 menus (Crank and Cassette). For example, in the first menu there should be Shimano 1x and Shimano 2x, if you select Shimano 1x then the crank drop down menu should be [53, 39], [52, 36], [50, 34], and Cassette should be [11, 28], [11, 32], [11, 36]. If you select Shimano 2x the Crank Menu should be 46, 36, 34, (yes sometimes the Crank is a series of single entries and sometimes it is a series of pairs) and the cassette should be [11, 36], [11, 534]. In the finished version there will be many more options, this is just an example.

Philosophically what is the best way to structure this data? Should I make each thing a list and then call it somehow? Should I make 1 giant dictionary that has everything correctly nested? And if I do that can someone point me in the correct direction to figure out the nesting syntax? Thank you so much and I hope this appropriate. Also when the final 2 drop downs are selected I need a function to call them and do a calculation with the integers, but I think once it is called correctly I know how to do the math and output it. I am doing the drop downs with tKinter.

Here is my code, please don't judge me, I am really struggling and trying my best to make sense of this :( And yes the shimano 1x / shimano 2x example from above is slightly different below, i am really trying to get total_gear_options_dict to work with the drop downs, but so far i was just using brand_options to test and make sure the drop down works (it does).

```<code>#HOW DO I NEST THIS? IS THIS EVEN CLOSE TO CORRECT? IT SAYS LINE 37 : IS WRONG
total_gear_options_dict = {
    ['shimano2xroad':
        {'chainring': {
            [53, 39],
            [52, 36],
            [50,34]},
            }
        'cassette': {
            [11, 23],
            [11, 25],
            [11, 28],
            [11, 32],
            [11, 34],
            }
    ]
    ['shimano1xgravel':
        'Chainring':
            [46, 36, 34],
        'Cassette': {
            [11, 36],
            [11,42]
            }
    ]
}
</code>```

Body:
this is my first Stack Overflow question so if this is not optimal please let me know, I appreciate the feedback.

I am studying Computer Science and for my final project I'm making a bicycle gear calculator. I want there to be 3 drop down menus (Brand and 1x or 2x, Crank, Cassette), the first menu (Brand) should auto-populate the next 2 menus (Crank and Cassette). For example, in the first menu there should be Shimano 1x and Shimano 2x, if you select Shimano 1x then the crank drop down menu should be [53, 39], [52, 36], [50, 34], and Cassette should be [11, 28], [11, 32], [11, 36]. If you select Shimano 2x the Crank Menu should be 46, 36, 34, (yes sometimes the Crank is a series of single entries and sometimes it is a series of pairs) and the cassette should be [11, 36], [11, 534]. In the finished version there will be many more options, this is just an example.

Philosophically what is the best way to structure this data? Should I make each thing a list and then call it somehow? Should I make 1 giant dictionary that has everything correctly nested? And if I do that can someone point me in the correct direction to figure out the nesting syntax? Thank you so much and I hope this appropriate. Also when the final 2 drop downs are selected I need a function to call them and do a calculation with the integers, but I think once it is called correctly I know how to do the math and output it. I am doing the drop downs with tKinter.

Here is my code, please don't judge me, I am really struggling and trying my best to make sense of this :( And yes the shimano 1x / shimano 2x example from above is slightly different below, i am really trying to get total_gear_options_dict to work with the drop downs, but so far i was just using brand_options to test and make sure the drop down works (it does).

#HOW DO I NEST THIS? IS THIS EVEN CLOSE TO CORRECT? IT SAYS LINE 37 : IS WRONG
total_gear_options_dict = {
    ['shimano2xroad':
        {'chainring': {
            [53, 39],
            [52, 36],
            [50,34]},
            }
        'cassette': {
            [11, 23],
            [11, 25],
            [11, 28],
            [11, 32],
            [11, 34],
            }
    ]
    ['shimano1xgravel':
        'Chainring':
            [46, 36, 34],
        'Cassette': {
            [11, 36],
            [11,42]
            }
    ]
}

Body:
The correct code ended up being as follows, thank you for all your input! Very close to what was posted by Cireo, except I went with 'chainring': { with the curly brace instead of a list, not sure if it would work either way but it definitely correctly works as posted below. You could do the tuples as Cireo posted for the combos (53, 39), that is technically preferred I suppose, but I went with lists only because it was easier to type and functions identical.

gearset = {
'Shimano 2x Road': {
    'chainring': {
        '53-39': [53, 39],
        '52-36': [52, 36],
        '50-34': [50, 34]
        },
    'cassette': {
        '11-34': [11, 34],
        '11-32': [11, 12, 13, 14, 16, 18, 20, 22, 25, 28, 32],
        '11-28': [11, 12, 13, 14, 15, 17, 19, 21, 23, 25, 28]
        }
    },
'Shimano 1x Gravel': {
    'chainring': {
        '46': [46],
        '36': [36],
        '34': [34]},
    'cassette': {
        '11-36': [11, 12, 13, 14, 15, 36],
        '11-42': [11, 14, 15, 19, 42]
        }
    },
'SRAM 2x Road': {
    'chainring': {
        '53-39': [53, 39],
        '52-36': [52, 36],
        '50-34': [50, 34]
        },
    'cassette': {
        '11-28': [11, 12, 20, 21, 22, 23, 24, 25, 26, 27, 28],
        '11-32': [11, 20, 21, 22, 23, 24, 25, 26, 27, 30, 32],
        '11-36': [11, 13, 15, 17, 19, 22, 25, 28, 32, 36]
        }
    },
'SRAM 1x Gravel': {
    'chainring': {
        '36': [36],
        '40': [40],
        '42': [42]
        },
    'cassette': {
        '10-26': [10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 26],  # range %260
        '10-28': [10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 24, 28],  # range %280
        '10-33': [10, 11, 12, 13, 14, 15, 17, 19, 21, 24, 28, 33], # range %330
        '10-36': [10, 11, 12, 13, 15, 17, 19, 21, 24, 28, 32, 36], # range %360
        '10-42': [10, 12, 14, 16, 18, 21, 24, 28, 32, 36, 42],
        '10-50': [10, 12, 14, 16, 18, 21, 24, 28, 32, 36, 42, 50]
        }
},
'Rotor 1x': {
    'chainring': {
        '54': [54],
        '52': [52],
        '50': [50],
        '48': [48],
        '46': [46],
        '44': [44],
        '42': [42],
        '40': [40],
        '38': [38]
    },
    'cassette': {
        '10-36': [10, 36],
        '10-39': [10, 39],
        '10-46': [10, 46],
        '11-36': [11, 36],
        '11-39': [11, 39],
        '11-46': [11, 46],
        '11-52': [11, 52]
        }
    }

}


问:
Type '<T>(array: T[], pred: (x: T) => boolean, index: number) => void' is not assignable to type '() => void'
I'm trying to create an extension method for Array.

This is what I've created:

```<code>interface Array<T> {
    moveServiceBranchInArray(): void;
}

Array.prototype.moveServiceBranchInArray = function<T> (array: T[], pred: (x: T) => boolean, index: number): void
{
    const curPos: number = array.findIndex(pred);
    index = Math.max(Math.min(index, array.length - 1), 0);

    if (curPos < 0) {
      return;
    }
    [array[curPos], array[index]] = [array[index], array[curPos]];
}
</code>```

Unfortunately I'm getting the error

"Type
'(array: T[], pred: (x: T) => boolean, index: number) => void' is not assignable to type '() => void'."

as shown in the title.  What gives, help appreciated.

答:
You should specify function arguments in your interface like this:

interface Array<T> {
    moveServiceBranchInArray(array: T[], pred: (x: T) => boolean, index: number): void;
}

Array.prototype.moveServiceBranchInArray = function<T> (array: T[], pred: (x: T) => boolean, index: number): void
{
    const curPos: number = array.findIndex(pred);
    index = Math.max(Math.min(index, array.length - 1), 0);

    if (curPos < 0) {
      return;
    }
    [array[curPos], array[index]] = [array[index], array[curPos]];
}
```

Body:
I'm trying to create an extension method for Array.

This is what I've created:

interface Array<T> {
    moveServiceBranchInArray(): void;
}

Array.prototype.moveServiceBranchInArray = function<T> (array: T[], pred: (x: T) => boolean, index: number): void
{
    const curPos: number = array.findIndex(pred);
    index = Math.max(Math.min(index, array.length - 1), 0);

    if (curPos < 0) {
      return;
    }
    [array[curPos], array[index]] = [array[index], array[curPos]];
}

Unfortunately I'm getting the error

"Type
'(array: T[], pred: (x: T) => boolean, index: number) => void' is not assignable to type '() => void'."

as shown in the title.  What gives, help appreciated.


问:
How to stop BERT from breaking apart specific words into word-piece
I am using a pre-trained BERT model to tokenize a text into meaningful tokens. However, the text has many specific words and I don't want BERT model to break them into word-pieces. Is there any solution to it?
For example:

```<code>tokenizer = BertTokenizer('bert-base-uncased-vocab.txt')
tokens = tokenizer.tokenize("metastasis")
</code>```

Create tokens like this:

```<code>['meta', '##sta', '##sis']
</code>```

However, I want to keep the whole words as one token, like this:

```<code>['metastasis']
</code>```

答:
You are free to add new tokens to the existing pretrained tokenizer, but then you need to train your model with the improved tokenizer (extra tokens).

Example:

```<code>from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
v = tokenizer.get_vocab()
print(len(v))
tokenizer.add_tokens(['whatever', 'underdog'])
v = tokenizer.get_vocab()
print(len(v))
</code>```

If token already exists like 'whatever' it will not be added.

Output:

```<code>30522
30523
</code>```

Body:
I am using a pre-trained BERT model to tokenize a text into meaningful tokens. However, the text has many specific words and I don't want BERT model to break them into word-pieces. Is there any solution to it?
For example:

tokenizer = BertTokenizer('bert-base-uncased-vocab.txt')
tokens = tokenizer.tokenize("metastasis")

Create tokens like this:

['meta', '##sta', '##sis']

However, I want to keep the whole words as one token, like this:

['metastasis']

Body:
You are free to add new tokens to the existing pretrained tokenizer, but then you need to train your model with the improved tokenizer (extra tokens).

Example:

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
v = tokenizer.get_vocab()
print(len(v))
tokenizer.add_tokens(['whatever', 'underdog'])
v = tokenizer.get_vocab()
print(len(v))

If token already exists like 'whatever' it will not be added.

Output:

30522
30523


问:
Guess Counting Control
I'm starting my studies in Python and I was assigned the Task to write code for a guessing game in which I have to control the total tries the player will have. I've described the functions, they're working (I believe...haha) but I can't make to "reset" the game when a wrong guess is input...
I wrote this:

```<code>guess_count = []
count_control = 1
def check_guess(letter,guess):
    if guess.isalpha() == False:
        print("Invalid!")
        return False
    elif guess.lower() < letter:
        print("Low")
        return False
    elif guess.lower() > letter:
        print("High")
        return False
    elif guess.lower() == letter:
        print("Correct!")
        return True
    else:
        print("anything")

def letter_guess(guess):
    check_guess ('a',guess)
    while len(guess_count) <= 3:
        if check_guess == True:
            return True
        elif check_guess == False:
            guess_count.append(count_control)
            guess = input("Try again \n")

letter_guess(input("test: "))
</code>```

UPDATE: I rewrote the code after some insights from other users and readings and came up with this:

```<code>class Game:

number_of_attempts = 3
no_more_attempts = "Game Over"

def attempt_down(self): #This will work as the counter of remaining lives.
    self.number_of_attempts -= 1
    print('Remaining Lives:',self.number_of_attempts)
def check_guess(self,letter):
    """
    Requires
    letter - a letter that has to be guessed
    guess - a input from the user with the guessed letter
    """
    while self.number_of_attempts > 0:
        guess = input ("Guess the letter: ")
        if guess.isalpha() == False:
            print("Invalid!")
        elif guess.lower() < letter:
            self.attempt_down()
            print("Low")
            print("Try Again!")
        elif guess.lower() > letter:
            self.attempt_down()
            print("High")
            print("Try Again!")
        elif guess.lower() == letter:
            print("Correct!")
            return True

    print (self.no_more_attempts)
    return False

game = Game()
"""
This is used to run the game.
Just insert the letter that
has to be guessed.
"""
teste1 = game.check_guess('g')
teste2 = game.check_guess('r')
</code>```

答:
The rub is in that you have a state of a game that you are tracking as global variables guess_count and count_control

This is an example of why python and other languages provide classes and objects:

```<code>class Game:

    def __init__(self):
        self.guess_count = []
        self.count_control = 1

    @staticmethod
    def check_guess(letter, guess):
        if guess.isalpha() == False:
            print("Invalid!")
            return False
        elif guess.lower() < letter:
            print("Low")
            return False
        elif guess.lower() > letter:
            print("High")
            return False
        elif guess.lower() == letter:
            print("Correct!")
            return True
        else:
            print("anything")

    def letter_guess(self, guess):
        self.check_guess('a', guess)
        while len(self.guess_count) <= 3:
            if self.check_guess('a', guess) == True:
                return True
            elif self.check_guess('a', guess) == False:
                self.guess_count.append(self.count_control)
                guess = input("Try again \n")

game = Game()
game.letter_guess(input("test: "))

game = Game()
game.letter_guess(input("test: "))
</code>```

Title: Guess Counting Control

Body:
I'm starting my studies in Python and I was assigned the Task to write code for a guessing game in which I have to control the total tries the player will have. I've described the functions, they're working (I believe...haha) but I can't make to "reset" the game when a wrong guess is input...
I wrote this:

guess_count = []
count_control = 1
def check_guess(letter,guess):
    if guess.isalpha() == False:
        print("Invalid!")
        return False
    elif guess.lower() < letter:
        print("Low")
        return False
    elif guess.lower() > letter:
        print("High")
        return False
    elif guess.lower() == letter:
        print("Correct!")
        return True
    else:
        print("anything")

def letter_guess(guess):
    check_guess ('a',guess)
    while len(guess_count) <= 3:
        if check_guess == True:
            return True
        elif check_guess == False:
            guess_count.append(count_control)
            guess = input("Try again \n")

letter_guess(input("test: "))

UPDATE: I rewrote the code after some insights from other users and readings and came up with this:

class Game:

number_of_attempts = 3
no_more_attempts = "Game Over"

def attempt_down(self): #This will work as the counter of remaining lives.
    self.number_of_attempts -= 1
    print('Remaining Lives:',self.number_of_attempts)
def check_guess(self,letter):
    """
    Requires
    letter - a letter that has to be guessed
    guess - a input from the user with the guessed letter
    """
    while self.number_of_attempts > 0:
        guess = input ("Guess the letter: ")
        if guess.isalpha() == False:
            print("Invalid!")
        elif guess.lower() < letter:
            self.attempt_down()
            print("Low")
            print("Try Again!")
        elif guess.lower() > letter:
            self.attempt_down()
            print("High")
            print("Try Again!")
        elif guess.lower() == letter:
            print("Correct!")
            return True

    print (self.no_more_attempts)
    return False

game = Game()
"""
This is used to run the game.
Just insert the letter that
has to be guessed.
"""
teste1 = game.check_guess('g')
teste2 = game.check_guess('r')

Body:
The rub is in that you have a state of a game that you are tracking as global variables guess_count and count_control

This is an example of why python and other languages provide classes and objects:

class Game:

    def __init__(self):
        self.guess_count = []
        self.count_control = 1

    @staticmethod
    def check_guess(letter, guess):
        if guess.isalpha() == False:
            print("Invalid!")
            return False
        elif guess.lower() < letter:
            print("Low")
            return False
        elif guess.lower() > letter:
            print("High")
            return False
        elif guess.lower() == letter:
            print("Correct!")
            return True
        else:
            print("anything")

    def letter_guess(self, guess):
        self.check_guess('a', guess)
        while len(self.guess_count) <= 3:
            if self.check_guess('a', guess) == True:
                return True
            elif self.check_guess('a', guess) == False:
                self.guess_count.append(self.count_control)
                guess = input("Try again \n")

game = Game()
game.letter_guess(input("test: "))

game = Game()
game.letter_guess(input("test: "))


问:
How does a ThreadPool work with passed variables
i am currently trying to accept incoming connections through a thread pool and it all works but raised the following question:

What if i get a new connection before the thread pool handles the previous one.
Is the Object passed to the function, in this case client, replaced with the new connection or will it remember both?

the reason i think it forgets the first client is because the passed variable is just a reference right?

The code looks like this:

```<code>public static void Initialize()
    {
        socket.Start();

        System.Threading.Thread newConnection = new System.Threading.Thread(() =>
        {
            while (isOnline)
            {
                System.Net.Sockets.TcpClient client = socket.AcceptTcpClient();
                System.Threading.ThreadPool.QueueUserWorkItem(HandleNewClient, client);
            }
        })
        {
            IsBackground = true,
            Name = "newConnection",
            Priority = System.Threading.ThreadPriority.Highest
        };
    }
</code>```

I hope this made it clear for you guys.
Thanks in advance for looking into this.

答:
I think you are basically trying to reinvent the WebServer or somthing close to it. My first advice is to never reinvent the wheel, if you got a fully gassed up car just standing there, keys in the ignition.

And especially web things have been solve dozens of times.

But if you got to do it yourself, generally you would get:

one public port

one thread that does nothing but listening to the Port, putting all it is receiving into a ConcurrentQueue, Channel or similar construct.

A giant Threadpool. We are talking about 50-100 Threads per CPU core on the average ASP.Net server.

those threads will then start looking into the queue if there is anything to do. You want to assign each client a different port, to keep the connections appart. And maybe even try to have 1 thread process each request from start to finish (however, there is no guarantee for that in practice; expect the responsible thread to change).

A negotiation would go somewhat like this:

Client to port 80: "Hey, I want to talk"

Server figures and locks a random, unused port: "Okay, you can talk to me on port 54321".

Client to port 54321: "Okay, here is what I want..."

Body:
i am currently trying to accept incoming connections through a thread pool and it all works but raised the following question:

What if i get a new connection before the thread pool handles the previous one.
Is the Object passed to the function, in this case client, replaced with the new connection or will it remember both?

the reason i think it forgets the first client is because the passed variable is just a reference right?

The code looks like this:

public static void Initialize()
    {
        socket.Start();

        System.Threading.Thread newConnection = new System.Threading.Thread(() =>
        {
            while (isOnline)
            {
                System.Net.Sockets.TcpClient client = socket.AcceptTcpClient();
                System.Threading.ThreadPool.QueueUserWorkItem(HandleNewClient, client);
            }
        })
        {
            IsBackground = true,
            Name = "newConnection",
            Priority = System.Threading.ThreadPriority.Highest
        };
    }

I hope this made it clear for you guys.
Thanks in advance for looking into this.


问:
close a port with nodeJS
As I write a program that listen on a port, lets say 8081, and then write another program that listen on the same port I will get this type of error message:

```<code>Error: listen EADDRINUSE
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1039:14)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (C:\NetBeansWorkPlace\nodeJS_Files\TutsNodeJS\static_file_server.js:36:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
</code>```

I found that the port is in use but how can I clear the port, or stop the app from listening on a given port?

答:
consult this  for a better understanding of this tool fuser

fuser -k -n tcp portNumber

Title: close a port with nodeJS

Body:
As I write a program that listen on a port, lets say 8081, and then write another program that listen on the same port I will get this type of error message:

Error: listen EADDRINUSE
    at errnoException (net.js:901:11)
    at Server._listen2 (net.js:1039:14)
    at listen (net.js:1061:10)
    at Server.listen (net.js:1127:5)
    at Object.<anonymous> (C:\NetBeansWorkPlace\nodeJS_Files\TutsNodeJS\static_file_server.js:36:4)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)

I found that the port is in use but how can I clear the port, or stop the app from listening on a given port?


问:
Parsing a CSV file and loading it into Core Data, in Swift
I'm working from a previous posting on AppCode called "Core Data Basics: Preload Data and Use Existing SQLite Database" located here: https://www.appcoda.com/core-data-preload-sqlite-database/

Within Simon Ng's posting is a function called parseCSV which does all the heavy lifting of scanning through a .csv and breaking it up into it's respective rows so that each row's elements can then be saved into their respective managedObjectContext in core data.

Unfortunately all of the code appears to be written in either Swift 1.0 or Swift 2.0 and I have been unable to understand the errors I'm getting in converting it into Swift 4.

I've made all of the changes suggested by Xcode with regards to "this" has been replaced with "that", with the final error telling me "Argument labels '(contentsOfURL:, encoding:, error:)' do not match any available overloads" which I have been unable to understand nor correct.

// https://www.appcoda.com/core-data-preload-sqlite-database/

```<code>    func parseCSV (contentsOfURL: NSURL, encoding: String.Encoding, error: NSErrorPointer) -> [(name:String, detail:String, price: String)]? {
        // Load the CSV file and parse it
        let delimiter = ","
        var items:[(name:String, detail:String, price: String)]?

        if let content = String(contentsOfURL: contentsOfURL, encoding: encoding, error: error) {
            items = []
            let lines:[String] = content.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) as [String]

            for line in lines {
                var values:[String] = []
                if line != "" {
                    // For a line with double quotes
                    // we use NSScanner to perform the parsing
                    if line.range(of: "\"") != nil {
                        var textToScan:String = line
                        var value:NSString?
                        var textScanner:Scanner = Scanner(string: textToScan)
                        while textScanner.string != "" {

                            if (textScanner.string as NSString).substring(to: 1) == "\"" {
                                textScanner.scanLocation += 1
                                textScanner.scanUpTo("\"", into: &value)
                                textScanner.scanLocation += 1
                            } else {
                                textScanner.scanUpTo(delimiter, into: &value)
                            }

                            // Store the value into the values array
                            values.append(value! as String)

                            // Retrieve the unscanned remainder of the string
                            if textScanner.scanLocation < textScanner.string.count {
                                textToScan = (textScanner.string as NSString).substring(from: textScanner.scanLocation + 1)
                            } else {
                                textToScan = ""
                            }
                            textScanner = Scanner(string: textToScan)
                        }

                        // For a line without double quotes, we can simply separate the string
                        // by using the delimiter (e.g. comma)
                    } else  {
                        values = line.components(separatedBy: delimiter)
                    }

                    // Put the values into the tuple and add it to the items array
                    let item = (name: values[0], detail: values[1], price: values[2])
                    items?.append(item)
                }
            }
        }

        return items
    }
</code>```

The 5th line:

if let content = String(contentsOfURL: contentsOfURL, encoding: encoding, error: error) {

is throwing the following error:

Argument labels '(contentsOfURL:, encoding:, error:)' do not match any available overloads

Which is beyond my understanding and skill level. I'm really just trying to find the best way of importing a comma separated .csv file into a core data object.

Any assistance would be appreciated. The original example by Simon Ng appears perfect for what I'm trying to achieve. It just hasn't been updated in a very long time.

答:
Because Scanner has been changed up in iOS 13 in ways that seem to be poorly explained, I rewrote this to work without it.  For my application, the header row is of interest, so it's captured separately; if it's not meaningful then that part can be omitted.

The code starts with workingText which has been read from whatever file or URL is the source of the data.

```<code>var headers : [String] = []
var data : [[String]]  = []

let workingLines = workingText.split{$0.isNewline}
if let headerLine = workingLines.first {
    headers = parseCsvLine(ln: String(headerLine))
    for ln in workingLines {
        if ln != headerLine {
            let fields = parseCsvLine(ln: String(ln))
            data.append(fields)
        }
    }
}

print("-----------------------------")
print("Headers: \(headers)")
print("Data:")
for d in data {
    print(d)    // gives each data row its own printed row; print(data) has no line breaks anywhere + is hard to read
}
print("-----------------------------")

func parseCsvLine(ln: String) -> [String] {
// takes a line of a CSV file and returns the separated values
// so input of 'a,b,2' should return ["a","b","2"]
// or input of '"Houston, TX","Hello",5,"6,7"' should return ["Houston, TX","Hello","5","6,7"]

let delimiter = ","
let quote = "\""
var nextTerminator = delimiter
var andDiscardDelimiter = false

var currentValue = ""
var allValues : [String] = []

for char in ln {
    let chr = String(char)
    if chr == nextTerminator {
        if andDiscardDelimiter {
            // we've found the comma after a closing quote. No action required beyond clearing this flag.
            andDiscardDelimiter = false
        }
        else {
            // we've found the comma or closing quote terminating one value
            allValues.append(currentValue)
            currentValue = ""
        }
        nextTerminator = delimiter  // either way, next thing we look for is the comma
    } else if chr == quote {
        // this is an OPENING quote, so clear currentValue (which should be nothing but maybe a single space):
        currentValue = ""
        nextTerminator = quote
        andDiscardDelimiter = true
    } else {
        currentValue += chr
    }
}
return allValues
</code>```

}

I freely acknowledge that I probably use more conversions to String than those smarter than I am in the ways of Apple strings, substrings, scanners, and such would find necessary.  Parsing a file of a few hundred rows x about a dozen columns, this approach seems to work fine; for something significantly larger, the extra overhead may start to matter.

Body:
I'm working from a previous posting on AppCode called "Core Data Basics: Preload Data and Use Existing SQLite Database" located here: https://www.appcoda.com/core-data-preload-sqlite-database/

Within Simon Ng's posting is a function called parseCSV which does all the heavy lifting of scanning through a .csv and breaking it up into it's respective rows so that each row's elements can then be saved into their respective managedObjectContext in core data.

Unfortunately all of the code appears to be written in either Swift 1.0 or Swift 2.0 and I have been unable to understand the errors I'm getting in converting it into Swift 4.

I've made all of the changes suggested by Xcode with regards to "this" has been replaced with "that", with the final error telling me "Argument labels '(contentsOfURL:, encoding:, error:)' do not match any available overloads" which I have been unable to understand nor correct.

// https://www.appcoda.com/core-data-preload-sqlite-database/

    func parseCSV (contentsOfURL: NSURL, encoding: String.Encoding, error: NSErrorPointer) -> [(name:String, detail:String, price: String)]? {
        // Load the CSV file and parse it
        let delimiter = ","
        var items:[(name:String, detail:String, price: String)]?

        if let content = String(contentsOfURL: contentsOfURL, encoding: encoding, error: error) {
            items = []
            let lines:[String] = content.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) as [String]

            for line in lines {
                var values:[String] = []
                if line != "" {
                    // For a line with double quotes
                    // we use NSScanner to perform the parsing
                    if line.range(of: "\"") != nil {
                        var textToScan:String = line
                        var value:NSString?
                        var textScanner:Scanner = Scanner(string: textToScan)
                        while textScanner.string != "" {

                            if (textScanner.string as NSString).substring(to: 1) == "\"" {
                                textScanner.scanLocation += 1
                                textScanner.scanUpTo("\"", into: &value)
                                textScanner.scanLocation += 1
                            } else {
                                textScanner.scanUpTo(delimiter, into: &value)
                            }

                            // Store the value into the values array
                            values.append(value! as String)

                            // Retrieve the unscanned remainder of the string
                            if textScanner.scanLocation < textScanner.string.count {
                                textToScan = (textScanner.string as NSString).substring(from: textScanner.scanLocation + 1)
                            } else {
                                textToScan = ""
                            }
                            textScanner = Scanner(string: textToScan)
                        }

                        // For a line without double quotes, we can simply separate the string
                        // by using the delimiter (e.g. comma)
                    } else  {
                        values = line.components(separatedBy: delimiter)
                    }

                    // Put the values into the tuple and add it to the items array
                    let item = (name: values[0], detail: values[1], price: values[2])
                    items?.append(item)
                }
            }
        }

        return items
    }

The 5th line:

if let content = String(contentsOfURL: contentsOfURL, encoding: encoding, error: error) {

is throwing the following error:

Argument labels '(contentsOfURL:, encoding:, error:)' do not match any available overloads

Which is beyond my understanding and skill level. I'm really just trying to find the best way of importing a comma separated .csv file into a core data object.

Any assistance would be appreciated. The original example by Simon Ng appears perfect for what I'm trying to achieve. It just hasn't been updated in a very long time.

Body:
Because Scanner has been changed up in iOS 13 in ways that seem to be poorly explained, I rewrote this to work without it.  For my application, the header row is of interest, so it's captured separately; if it's not meaningful then that part can be omitted.

The code starts with workingText which has been read from whatever file or URL is the source of the data.

var headers : [String] = []
var data : [[String]]  = []

let workingLines = workingText.split{$0.isNewline}
if let headerLine = workingLines.first {
    headers = parseCsvLine(ln: String(headerLine))
    for ln in workingLines {
        if ln != headerLine {
            let fields = parseCsvLine(ln: String(ln))
            data.append(fields)
        }
    }
}

print("-----------------------------")
print("Headers: \(headers)")
print("Data:")
for d in data {
    print(d)    // gives each data row its own printed row; print(data) has no line breaks anywhere + is hard to read
}
print("-----------------------------")

func parseCsvLine(ln: String) -> [String] {
// takes a line of a CSV file and returns the separated values
// so input of 'a,b,2' should return ["a","b","2"]
// or input of '"Houston, TX","Hello",5,"6,7"' should return ["Houston, TX","Hello","5","6,7"]

let delimiter = ","
let quote = "\""
var nextTerminator = delimiter
var andDiscardDelimiter = false

var currentValue = ""
var allValues : [String] = []

for char in ln {
    let chr = String(char)
    if chr == nextTerminator {
        if andDiscardDelimiter {
            // we've found the comma after a closing quote. No action required beyond clearing this flag.
            andDiscardDelimiter = false
        }
        else {
            // we've found the comma or closing quote terminating one value
            allValues.append(currentValue)
            currentValue = ""
        }
        nextTerminator = delimiter  // either way, next thing we look for is the comma
    } else if chr == quote {
        // this is an OPENING quote, so clear currentValue (which should be nothing but maybe a single space):
        currentValue = ""
        nextTerminator = quote
        andDiscardDelimiter = true
    } else {
        currentValue += chr
    }
}
return allValues

}

I freely acknowledge that I probably use more conversions to String than those smarter than I am in the ways of Apple strings, substrings, scanners, and such would find necessary.  Parsing a file of a few hundred rows x about a dozen columns, this approach seems to work fine; for something significantly larger, the extra overhead may start to matter.


问:
Is there a shortcut for switching between panels in eclipse?
Eclipse has an MDI structure (Multi Document Interface), so the search panel, the package explorer and the code editor can all be open in one window, but I haven't found a keyboard shortcut for switching between these panels. For example, after I search the code-base, I would love to have a quick shortcut for going back to the code editor.</p>

答: And if you want to switch between perspectives its: Crtl + F8 and Ctrl + Shift + F8. You can go to Help > Key Assist... for a full list of shortcuts (this list will change depending on the active editor etc.).


问:
Matplotlib plot for loop issue
I'm trying to plot time series data in matplotlib using a for loop.  The goal is to dynamically plot 'n' years worth of daily closing price data.  If i load 7 years of data, I get 7 unique plots.  I have created a summary of the start and end dates for a data set, yearly_date_ranges (date is the index).  I use this to populate start and end dates.  The code I've written so far produces 7 plots of all daily data instead of 7 unique plots, one for each year.  Any help is appreciated. Thanks in advance!</p>

```<code>    yearly_date_ranges
              start        end
    Date
    2014 2014-04-01 2014-12-31
    2015 2015-01-01 2015-12-31
    2016 2016-01-01 2016-12-31
    2017 2017-01-01 2017-12-31
    2018 2018-01-01 2018-12-31
    2019 2019-01-01 2019-12-31
    2020 2020-01-01 2020-05-28

    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline

    fig = plt.figure(figsize=(12,20))
    for i in range(len(yearly_date_ranges)):
        ax = fig.add_subplot(len(yearly_date_ranges),1,i + 1)
        for row in yearly_date_ranges.itertuples(index=False):
            start = row.start
            end = row.end
            subset = data[start:end]
            ax.plot(subset['Close'])

    plt.show()
</code>```

答:
Dynamically you should do something like this:</p>

```<code>fig, axes = plt.subplots(7,1, figsize=(12,20))

years = data.index.year

for ax, (k,d) in zip(axes.ravel(), data.groupby(years)):
    d.plot(y='Close', ax=ax)
</code>```

Title: Matplotlib plot for loop issue

Body:
I'm trying to plot time series data in matplotlib using a for loop.  The goal is to dynamically plot 'n' years worth of daily closing price data.  If i load 7 years of data, I get 7 unique plots.  I have created a summary of the start and end dates for a data set, yearly_date_ranges (date is the index).  I use this to populate start and end dates.  The code I've written so far produces 7 plots of all daily data instead of 7 unique plots, one for each year.  Any help is appreciated. Thanks in advance!

    yearly_date_ranges
              start        end
    Date
    2014 2014-04-01 2014-12-31
    2015 2015-01-01 2015-12-31
    2016 2016-01-01 2016-12-31
    2017 2017-01-01 2017-12-31
    2018 2018-01-01 2018-12-31
    2019 2019-01-01 2019-12-31
    2020 2020-01-01 2020-05-28

    import pandas as pd
    import matplotlib.pyplot as plt
    %matplotlib inline

    fig = plt.figure(figsize=(12,20))
    for i in range(len(yearly_date_ranges)):
        ax = fig.add_subplot(len(yearly_date_ranges),1,i + 1)
        for row in yearly_date_ranges.itertuples(index=False):
            start = row.start
            end = row.end
            subset = data[start:end]
            ax.plot(subset['Close'])

    plt.show()

Body:
Dynamically you should do something like this:

fig, axes = plt.subplots(7,1, figsize=(12,20))

years = data.index.year

for ax, (k,d) in zip(axes.ravel(), data.groupby(years)):
    d.plot(y='Close', ax=ax)


问:
Why does a nested loop perform much faster than the flattened one?
UPDATE

Sorry guys but the pervious number is INACCURATE. When I tested the previous code I used tqdm to see the expected time and the function will hurt the performance when the iterable object is very long. So I get 18.22s, which is 9 times longer than 2.43s.

HOWEVER, the conclusion is CONSISTENT: The nested loop is much FASTER. When the iteration time is 100^5, the difference is significant: 321.49 vs 210.05. There is about 1.53-time gap between them. Generally, we don't face this kind of long iteration, I'm just curious to know reason of the anomalistic situation.

My python version is 3.7.3. I use 13-inch MacBookPro2019 with 2.4 GHz Intel Core i5. The OS is macOS Mojave 10.14.6

I found a weird situation in python as follows:

import time

start = time.time()
# flattened loop
for i in range(100**4):
    pass
print(time.time() - start) # 18.22(Wrong! Should be 3.09)

# nested loop
start = time.time()
for i in range(100):
    for j in range(100):
        for k in range(100):
            for l in range(100):
                pass
print(time.time() - start) # 2.43
```

The two kinds of loops above have the same iteration times. However the nested loop(2.43s) is running much faster that the flattened one(18.22s). The difference is bigger with the increasing of the iteration time. Hoes does this happen?

答:
Firstly, that is not a reliable way of measuring code execution. Let us consider this code instead (to be runned in IPython), which does not include the power calculation in the loop, and has some computation just to make sure that it cannot be "optimized" to "please do nothing".

```<code>def flattened_loop(n):
    x = 0
    for i in range(n):
        x += 1
    return x

def nested4_loop(n):
    x = 0
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for l in range(n):
                    x += 1
    return x

print(f'{"n":>4s}  {"n ** 4":>16s}  {"flattened":>18s}  {"nested4":>18s}')
for n in range(10, 120, 10):
    t1 = %timeit -q -o flattened_loop(n)
    t2 = %timeit -q -o nested4_loop(n)
    print(f'{n:4}  {n**4:16}  {t1.best * 1e3:15.3f} ms  {t2.best * 1e3:15.3f} ms')
</code>```

   n            n ** 4           flattened             nested4
  10             10000            0.526 ms            0.653 ms
  20            160000            8.561 ms            8.459 ms
  30            810000           43.077 ms           39.417 ms
  40           2560000          136.709 ms          121.422 ms
  50           6250000          331.748 ms          291.132 ms
  60          12960000          698.014 ms          599.228 ms
  70          24010000         1280.681 ms         1081.062 ms
  80          40960000         2187.500 ms         1826.629 ms
  90          65610000         3500.463 ms         2942.909 ms
 100         100000000         5349.721 ms         4437.965 ms
 110         146410000         7835.733 ms         6474.588 ms
```

<p>which shows that a difference does exists and it is larger for larger <code>n</code>.</p>

<p>Is the first one running more bytecode? No. We can clearly see this through <code>dis</code>:</p>

<ul>
<li><code>flattened_loop()</code></li>
</ul>

```import dis

dis.dis(flattened_loop)
```

<pre class="lang-none prettyprint-override"><code>  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

  3           4 SETUP_LOOP              24 (to 30)
              6 LOAD_GLOBAL              0 (range)
              8 LOAD_FAST                0 (n)
             10 CALL_FUNCTION            1
             12 GET_ITER
        >>   14 FOR_ITER                12 (to 28)
             16 STORE_FAST               2 (i)

  4          18 LOAD_FAST                1 (x)
             20 LOAD_CONST               2 (1)
             22 INPLACE_ADD
             24 STORE_FAST               1 (x)
             26 JUMP_ABSOLUTE           14
        >>   28 POP_BLOCK

  5     >>   30 LOAD_FAST                1 (x)
             32 RETURN_VALUE
</code>```

nested4_loop()

```<code>dis.dis(nested4_loop)
</code>```

  9           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

 10           4 SETUP_LOOP              78 (to 84)
              6 LOAD_GLOBAL              0 (range)
              8 LOAD_FAST                0 (n)
             10 CALL_FUNCTION            1
             12 GET_ITER
        >>   14 FOR_ITER                66 (to 82)
             16 STORE_FAST               2 (i)

 11          18 SETUP_LOOP              60 (to 80)
             20 LOAD_GLOBAL              0 (range)
             22 LOAD_FAST                0 (n)
             24 CALL_FUNCTION            1
             26 GET_ITER
        >>   28 FOR_ITER                48 (to 78)
             30 STORE_FAST               3 (j)

 12          32 SETUP_LOOP              42 (to 76)
             34 LOAD_GLOBAL              0 (range)
             36 LOAD_FAST                0 (n)
             38 CALL_FUNCTION            1
             40 GET_ITER
        >>   42 FOR_ITER                30 (to 74)
             44 STORE_FAST               4 (k)

 13          46 SETUP_LOOP              24 (to 72)
             48 LOAD_GLOBAL              0 (range)
             50 LOAD_FAST                0 (n)
             52 CALL_FUNCTION            1
             54 GET_ITER
        >>   56 FOR_ITER                12 (to 70)
             58 STORE_FAST               5 (l)

 14          60 LOAD_FAST                1 (x)
             62 LOAD_CONST               2 (1)
             64 INPLACE_ADD
             66 STORE_FAST               1 (x)
             68 JUMP_ABSOLUTE           56
        >>   70 POP_BLOCK
        >>   72 JUMP_ABSOLUTE           42
        >>   74 POP_BLOCK
        >>   76 JUMP_ABSOLUTE           28
        >>   78 POP_BLOCK
        >>   80 JUMP_ABSOLUTE           14
        >>   82 POP_BLOCK

 15     >>   84 LOAD_FAST                1 (x)
             86 RETURN_VALUE
```

<hr>

<p>Are the numbers in the single loops getting too big? No.</p>

```import sys

print([(n, sys.getsizeof(n), n ** 4, sys.getsizeof(n ** 4)) for n in (10, 110)])
# [(10, 28, 10000, 28), (110, 28, 146410000, 28)]
```

<p>Is the power operation (not timed in my code, but timed in yours) explaining the timing difference (timed only once because constant computations get cached in Python)? No.</p>

```%timeit -r1 -n1 100 ** 4
# loop, best of 1: 708 ns per loop
```

<hr>

<p>So, what is happening?</p>

<p>At this point this is just speculation, but, given that we have ruled out at least some of the potential candidates, I believe that this is due some caching mechanism that is taking place in the nested version.
Such caching is probably in place to speed up the notoriously comparatively slow explicit looping.</p>

<hr>

<p>If we repeat the same test with Numba compilation (where loops gets lifted, i.e. executed without the boilerplate required by Python to ensure its dynamism), we do actually get:</p>

```import numba as nb

@nb.jit
def flattened_loop_nb(n):
    x = 0
    for i in range(n):
        x += 1
    return x

@nb.jit
def nested4_loop_nb(n):
    x = 0
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for l in range(n):
                    x += 1
    return x

flattened_loop_nb(100)  # trigger compilation
nested4_loop_nb(100)  # trigger compilation

print(f'{"n":>4s}  {"n ** 4":>16s}  {"flattened":>18s}  {"nested4":>18s}')
for n in range(10, 120, 10):
    m = n ** 4
    t1 = %timeit -q -o flattened_loop_nb(m)
    t2 = %timeit -q -o nested4_loop_nb(n)
    print(f'{n:4}  {n**4:16}  {t1.best * 1e6:15.3f} µs  {t2.best * 1e6:15.3f} µs')
```

<pre class="lang-none prettyprint-override"><code>   n            n ** 4           flattened             nested4
  10             10000            0.195 µs            0.199 µs
  20            160000            0.196 µs            0.201 µs
  30            810000            0.196 µs            0.200 µs
  40           2560000            0.195 µs            0.197 µs
  50           6250000            0.193 µs            0.199 µs
  60          12960000            0.195 µs            0.199 µs
  70          24010000            0.197 µs            0.200 µs
  80          40960000            0.195 µs            0.199 µs
  90          65610000            0.194 µs            0.197 µs
 100         100000000            0.195 µs            0.199 µs
 110         146410000            0.194 µs            0.199 µs
</code>```

Slightly slower (but largely independent on n)  execution speed for the nested loops (as expected).

Body:
UPDATE

Sorry guys but the pervious number is INACCURATE. When I tested the previous code I used tqdm to see the expected time and the function will hurt the performance when the iterable object is very long. So I get 18.22s, which is 9 times longer than 2.43s.

HOWEVER, the conclusion is CONSISTENT: The nested loop is much FASTER. When the iteration time is 100^5, the difference is significant: 321.49 vs 210.05. There is about 1.53-time gap between them. Generally, we don't face this kind of long iteration, I'm just curious to know reason of the anomalistic situation.

My python version is 3.7.3. I use 13-inch MacBookPro2019 with 2.4 GHz Intel Core i5. The OS is macOS Mojave 10.14.6

I found a weird situation in python as follows:

import time

start = time.time()
# flattened loop
for i in range(100**4):
    pass
print(time.time() - start) # 18.22(Wrong! Should be 3.09)

# nested loop
start = time.time()
for i in range(100):
    for j in range(100):
        for k in range(100):
            for l in range(100):
                pass
print(time.time() - start) # 2.43

The two kinds of loops above have the same iteration times. However the nested loop(2.43s) is running much faster that the flattened one(18.22s). The difference is bigger with the increasing of the iteration time. Hoes does this happen?

Body:
Firstly, that is not a reliable way of measuring code execution. Let us consider this code instead (to be runned in IPython), which does not include the power calculation in the loop, and has some computation just to make sure that it cannot be "optimized" to "please do nothing".

def flattened_loop(n):
    x = 0
    for i in range(n):
        x += 1
    return x

def nested4_loop(n):
    x = 0
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for l in range(n):
                    x += 1
    return x

print(f'{"n":>4s}  {"n ** 4":>16s}  {"flattened":>18s}  {"nested4":>18s}')
for n in range(10, 120, 10):
    t1 = %timeit -q -o flattened_loop(n)
    t2 = %timeit -q -o nested4_loop(n)
    print(f'{n:4}  {n**4:16}  {t1.best * 1e3:15.3f} ms  {t2.best * 1e3:15.3f} ms')

   n            n ** 4           flattened             nested4
  10             10000            0.526 ms            0.653 ms
  20            160000            8.561 ms            8.459 ms
  30            810000           43.077 ms           39.417 ms
  40           2560000          136.709 ms          121.422 ms
  50           6250000          331.748 ms          291.132 ms
  60          12960000          698.014 ms          599.228 ms
  70          24010000         1280.681 ms         1081.062 ms
  80          40960000         2187.500 ms         1826.629 ms
  90          65610000         3500.463 ms         2942.909 ms
 100         100000000         5349.721 ms         4437.965 ms
 110         146410000         7835.733 ms         6474.588 ms

which shows that a difference does exists and it is larger for larger n.

Is the first one running more bytecode? No. We can clearly see this through dis:

flattened_loop()

import dis

dis.dis(flattened_loop)

  2           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

  3           4 SETUP_LOOP              24 (to 30)
              6 LOAD_GLOBAL              0 (range)
              8 LOAD_FAST                0 (n)
             10 CALL_FUNCTION            1
             12 GET_ITER
        >>   14 FOR_ITER                12 (to 28)
             16 STORE_FAST               2 (i)

  4          18 LOAD_FAST                1 (x)
             20 LOAD_CONST               2 (1)
             22 INPLACE_ADD
             24 STORE_FAST               1 (x)
             26 JUMP_ABSOLUTE           14
        >>   28 POP_BLOCK

  5     >>   30 LOAD_FAST                1 (x)
             32 RETURN_VALUE

nested4_loop()

dis.dis(nested4_loop)

  9           0 LOAD_CONST               1 (0)
              2 STORE_FAST               1 (x)

 10           4 SETUP_LOOP              78 (to 84)
              6 LOAD_GLOBAL              0 (range)
              8 LOAD_FAST                0 (n)
             10 CALL_FUNCTION            1
             12 GET_ITER
        >>   14 FOR_ITER                66 (to 82)
             16 STORE_FAST               2 (i)

 11          18 SETUP_LOOP              60 (to 80)
             20 LOAD_GLOBAL              0 (range)
             22 LOAD_FAST                0 (n)
             24 CALL_FUNCTION            1
             26 GET_ITER
        >>   28 FOR_ITER                48 (to 78)
             30 STORE_FAST               3 (j)

 12          32 SETUP_LOOP              42 (to 76)
             34 LOAD_GLOBAL              0 (range)
             36 LOAD_FAST                0 (n)
             38 CALL_FUNCTION            1
             40 GET_ITER
        >>   42 FOR_ITER                30 (to 74)
             44 STORE_FAST               4 (k)

 13          46 SETUP_LOOP              24 (to 72)
             48 LOAD_GLOBAL              0 (range)
             50 LOAD_FAST                0 (n)
             52 CALL_FUNCTION            1
             54 GET_ITER
        >>   56 FOR_ITER                12 (to 70)
             58 STORE_FAST               5 (l)

 14          60 LOAD_FAST                1 (x)
             62 LOAD_CONST               2 (1)
             64 INPLACE_ADD
             66 STORE_FAST               1 (x)
             68 JUMP_ABSOLUTE           56
        >>   70 POP_BLOCK
        >>   72 JUMP_ABSOLUTE           42
        >>   74 POP_BLOCK
        >>   76 JUMP_ABSOLUTE           28
        >>   78 POP_BLOCK
        >>   80 JUMP_ABSOLUTE           14
        >>   82 POP_BLOCK

 15     >>   84 LOAD_FAST                1 (x)
             86 RETURN_VALUE

Are the numbers in the single loops getting too big? No.

import sys

print([(n, sys.getsizeof(n), n ** 4, sys.getsizeof(n ** 4)) for n in (10, 110)])
# [(10, 28, 10000, 28), (110, 28, 146410000, 28)]

Is the power operation (not timed in my code, but timed in yours) explaining the timing difference (timed only once because constant computations get cached in Python)? No.

%timeit -r1 -n1 100 ** 4
# loop, best of 1: 708 ns per loop

So, what is happening?

At this point this is just speculation, but, given that we have ruled out at least some of the potential candidates, I believe that this is due some caching mechanism that is taking place in the nested version.
Such caching is probably in place to speed up the notoriously comparatively slow explicit looping.

If we repeat the same test with Numba compilation (where loops gets lifted, i.e. executed without the boilerplate required by Python to ensure its dynamism), we do actually get:

import numba as nb

@nb.jit
def flattened_loop_nb(n):
    x = 0
    for i in range(n):
        x += 1
    return x

@nb.jit
def nested4_loop_nb(n):
    x = 0
    for i in range(n):
        for j in range(n):
            for k in range(n):
                for l in range(n):
                    x += 1
    return x

flattened_loop_nb(100)  # trigger compilation
nested4_loop_nb(100)  # trigger compilation

print(f'{"n":>4s}  {"n ** 4":>16s}  {"flattened":>18s}  {"nested4":>18s}')
for n in range(10, 120, 10):
    m = n ** 4
    t1 = %timeit -q -o flattened_loop_nb(m)
    t2 = %timeit -q -o nested4_loop_nb(n)
    print(f'{n:4}  {n**4:16}  {t1.best * 1e6:15.3f} µs  {t2.best * 1e6:15.3f} µs')

   n            n ** 4           flattened             nested4
  10             10000            0.195 µs            0.199 µs
  20            160000            0.196 µs            0.201 µs
  30            810000            0.196 µs            0.200 µs
  40           2560000            0.195 µs            0.197 µs
  50           6250000            0.193 µs            0.199 µs
  60          12960000            0.195 µs            0.199 µs
  70          24010000            0.197 µs            0.200 µs
  80          40960000            0.195 µs            0.199 µs
  90          65610000            0.194 µs            0.197 µs
 100         100000000            0.195 µs            0.199 µs
 110         146410000            0.194 µs            0.199 µs

Slightly slower (but largely independent on n)  execution speed for the nested loops (as expected).


问:
Snowflake Flatten scenario
I have some variant structure in a source table that I need to read, lookup and get into another variant structure into a target table.

-- Source table: clicks

```<code>create table clicks
(payload variant
);
</code>```

-- set data in clicks

```<code>insert into clicks
select
object_construct(
  'language', 'en-us',
  'browser', 'chrome',
  'color', '35',
  'event_ids', '190,195'
)
union
object_construct(
  'language', 'en-us',
  'browser', 'chrome',
  'color', '32',
  'event_ids', '201,203,190,195'
)
union
select
object_construct(
  'language', 'en-us',
  'browser', 'mozilla',
  'color', '38',
  'event_ids', '188,190,202,203,195,176'
);
</code>```

-- Target table: clicks_processed

```<code>create table clicks_processed
(payload variant,
 click_events variant )
</code>```

Lookup table: click_event

```<code>create table click_event
(
  key varchar,
  event_id varchar,
  desc varchar
)
</code>```

-- set up data for click_event

```<code>insert into click_event (key,event_id,desc)
select 'event201','201','pic_click'
union
select 'event202','202','vid_view'
union
select 'event203','203','download'
</code>```

Requirement:
Insert records into clicks_processed table.

Payload column of clicks_processed table is the same payload from clicks table.

click_events column of clicks_processed table: event_ids key has to be pulled out of the clicks.payload and joined with lookup table "click_event" to form a variant that will be inserted to click_events column of clicks_processed

Desired output: clicks_processed (only matching event_id from click_event get populated under click_events)

Note: The first record has null for click_events because none of the event_ids match from the click_event lookup table (still need the record)

Current code I've come up with:

```<code>select max(payload),
object_agg(e.key,object_construct(
'code', e.event_id,
'desc', e.desc
)) as click_events
from clicks c, table(flatten(input => split(c.payload:event_ids,','))) as f
inner join click_event e on e.event_id = f.value
group by seq
</code>```

This works fine if all the records have matching event_ids from that of click_event otherwise not (first record in the example above), a left join with click_event also didn't help.

Also, not sure if this is the best piece of code, especially worried about usage of max(payload) and group by. In real scenario, the payload is huge with about 500 keys and the event_ids can hold around 30-50 events which means the flatten also blows up as many records.

Thanks!

答:
```<code>select any_value(payload),
       object_agg(e.key,object_construct(
            'code', e.event_id,
            'desc', e.desc
            )) as click_events
from (
  select f.seq, f.value::varchar as value, c.payload
  from clicks c,
  lateral flatten(input => split(c.payload:event_ids,',')) as f
  ) a
left join click_event e
  on a.value = e.event_id
group by a.seq;
</code>```

Flatten the array and then join back to the click_event as a left join.  This gives you an empty array as opposed to a NULL, though.

Also, leverage any_value() function over the max() function, since that value will always be the same across the seq value.

Title: Snowflake Flatten scenario

Body:
I have some variant structure in a source table that I need to read, lookup and get into another variant structure into a target table.

-- Source table: clicks

create table clicks
(payload variant
);

-- set data in clicks

insert into clicks
select
object_construct(
  'language', 'en-us',
  'browser', 'chrome',
  'color', '35',
  'event_ids', '190,195'
)
union
object_construct(
  'language', 'en-us',
  'browser', 'chrome',
  'color', '32',
  'event_ids', '201,203,190,195'
)
union
select
object_construct(
  'language', 'en-us',
  'browser', 'mozilla',
  'color', '38',
  'event_ids', '188,190,202,203,195,176'
);

-- Target table: clicks_processed

create table clicks_processed
(payload variant,
 click_events variant )

Lookup table: click_event

create table click_event
(
  key varchar,
  event_id varchar,
  desc varchar
)

-- set up data for click_event

insert into click_event (key,event_id,desc)
select 'event201','201','pic_click'
union
select 'event202','202','vid_view'
union
select 'event203','203','download'

Requirement:
Insert records into clicks_processed table.

Payload column of clicks_processed table is the same payload from clicks table.

click_events column of clicks_processed table: event_ids key has to be pulled out of the clicks.payload and joined with lookup table "click_event" to form a variant that will be inserted to click_events column of clicks_processed

Desired output: clicks_processed (only matching event_id from click_event get populated under click_events)

Note: The first record has null for click_events because none of the event_ids match from the click_event lookup table (still need the record)

Current code I've come up with:

select max(payload),
object_agg(e.key,object_construct(
'code', e.event_id,
'desc', e.desc
)) as click_events
from clicks c, table(flatten(input => split(c.payload:event_ids,','))) as f
inner join click_event e on e.event_id = f.value
group by seq

This works fine if all the records have matching event_ids from that of click_event otherwise not (first record in the example above), a left join with click_event also didn't help.

Also, not sure if this is the best piece of code, especially worried about usage of max(payload) and group by. In real scenario, the payload is huge with about 500 keys and the event_ids can hold around 30-50 events which means the flatten also blows up as many records.

Thanks!

Body:
select any_value(payload),
       object_agg(e.key,object_construct(
            'code', e.event_id,
            'desc', e.desc
            )) as click_events
from (
  select f.seq, f.value::varchar as value, c.payload
  from clicks c,
  lateral flatten(input => split(c.payload:event_ids,',')) as f
  ) a
left join click_event e
  on a.value = e.event_id
group by a.seq;

Flatten the array and then join back to the click_event as a left join.  This gives you an empty array as opposed to a NULL, though.

Also, leverage any_value() function over the max() function, since that value will always be the same across the seq value.


问:
How can I associate .sh files with Cygwin?
I'd like to run a long rsync command in Cygwin by double clicking on a .sh file in Windows.  It must start in the file's containing directory (e.g. /cygdrive/c/scripts/) so that relative paths work.  Anyone gotten this to work?

Note: I've just found here, a Cygwin package that manages Windows context menus (Bash Prompt Here).  It might have some clues.

答:
Here is my solution.  It works well for my *.sh scripts
regardless of where they are in the directory hierarchy.
Notice that I cd to the cygpath dirname before calling
bash on the cygpath.  It just works.</p>

```<code>assoc .sh=bashscript

ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'
</code>```

Body:
Here is my solution.  It works well for my *.sh scripts
regardless of where they are in the directory hierarchy.
Notice that I cd to the cygpath dirname before calling
bash on the cygpath.  It just works.

assoc .sh=bashscript

ftype bashscript=C:\cygwin\bin\bash.exe --login -i -c 'cd "$(dirname "$(cygpath -u "%1")")"; bash "$(cygpath -u "%1")"'

LastEditorDisplayName: Jon Ericson

ContentLicense: CC BY-SA 2.5


问:
A little confused with Big O
So I have a quick question on how to verify the big O of a function.

for example: a quicksort algorithm sorting an array of 5000000 element yields a time interval of 0.008524 seconds, running the same algorithm with 1000000 element yields 0.017909.  How would I check the big O if my quicksort is/is not big O of n*log(n)??

What I think I understand: n increased by 2  thus the runtime should increase by 2*log(2)?

f(n) = 0.008524 -> n log (n)

f(2n) = 0.017909 ->2n*log(2n)

答:
Big-O notation is asymptotic.  That means it only applies in the limit as n gets large.

There are many reasons why sorting with 50 and 100 elements might not track O(n log n), caching effects being a likely candidate.  If you try 100,000 versus 200,000 versus 1 million, you will probably find it tracks a little better.

Another possibility is that most quicksort implementations are only O(n log n) on average; some inputs will take longer.  The odds of encountering such a pathological input are higher for 50 elements than for 100,000.

Ultimately, though, you do not "verify" big-O run time; you prove it based on what the algorithm does.

Title: A little confused with Big O