javascript – Best combination of a sum between two parameters in an array of objects

I am trying to build a simple algorithm to achieve the best combination of values based on two params in an array of objects.

The whole code is available here

First I have an array holding objects. The items which will be analyzed and packed into volumes together. All of the values are in percentages.

const nonStackableItems = (
    {
      id: 0,
      m2: 15,
      m3: 11,
      weight: 20
    },
    {
      id: 1,
      m2: 25,
      m3: 12,
      weight: 42
    },
    {
      id: 2,
      m2: 50,
      m3: 13,
      weight: 40
    },
    {
      id: 3,
      m2: 65,
      m3: 14,
      weight: 25
    }
  );

The idea is to combine these objects into packages, respecting the maximum of 100% for each value (except for m3 in this case, as all the packages should have enough height in this first analysis).

The approach that I gave is just not good enough, as I am sorting this array by m2 then by weight, call the function and then compare the length of both, and then choose the result that creates less volumes.

This is the piece of code that does the calculations:

function nSVolHelper(arr, vol, param1, param2) {
    let newVol = {
      id: vol.length,
      m2: 0,
      m3: 0,
      weight: 0
    };
    for (let i = 0; i < arr.length; i++) {
      const validation =
        newVol(param1) + arr(i)(param1) < 100 &&
        newVol.m2 + arr(i)(param2) < 100;
      if (validation) {
        newVol.m2 += arr(i).m2;
        newVol.m3 += arr(i).m3;
        newVol.weight += arr(i).weight;
      }
      if (!validation) {
        return nSVolHelper(arr.slice(i), (...vol, newVol), param1, param2);
      }
    }
    vol.push(newVol);
    return vol;
  }

  function nSVol(arr, param1, param2) {
    return nSVolHelper(arr, (), param1, param2);
  }

I would like to find a way of doing this without taking as a base the order of the array, to get the finest calculation without running unnecessary code, and I get the feeling that this approach of mine is just not reliable as well.

As an example, for better understanding:

If I pass the array sorted by weight I get a create 2 volumes.

console.log(
    "call",
    nSVol(
      nonStackableItems.sort((a, b) => a.weight - b.weight),
      "weight",
      "m2"
    )

If I pass this same array sorted by m2 I get 3 volumes.

console.log(
    "call",
    nSVol(
      nonStackableItems.sort((a, b) => a.m2 - b.m2),
      "weight",
      "m2"
    )

This was the best approach that I could find, but I feel that there could be another way of thinking of this.

Custom GET parameters not consistently visible in Google Analytics

I want to track custom GET parameters with Google Analytics. I don’t want to create anything inside the GA account (UTM and the rest of it). I’ve added this to my code:

<script>
    (function(i,s,o,g,r,a,m){i('GoogleAnalyticsObject')=r;i(r)=i(r)||function(){
        (i(r).q=i(r).q||()).push(arguments)},i(r).l=1*new Date();a=s.createElement(o),
        m=s.getElementsByTagName(o)(0);a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

    ga('create', 'xxxxxxxx', 'auto');
    // set of parameters tracked
    ga('set','parameter','value');
    ga('set','anotherparam','anothervalue');
    ga('set','customparam','customvalue');
    ga('send', 'pageview');
</script>

This was tested simply by visiting

www.mysite.com/somepage.html?parameter=value

Or

www.mysite.com/another-page.html?anotherparam=anothervalue

etc.

After opening links directly, and checking GA dashboard / panel at the same time, the links were visible in the Realtime section. However, not all of them were visible inside Acquisition or Behavior parts of GA dashboard. As far as I can tell, there are no patterns to when the landings are detected (the links are opened on both a desktop PC running Windows, and Android phone via Google Chrome, sometimes they are visible, other times they’re not visible).

Finally, my question.

How can I capture page landings with a custom GET parameter, without the UTM tracking codes? Can it be done through my JavaScript code alone? I do not want to create custom dimensions and custom definitions inside Google Analytics.

php – Warning: mysqli_stmt::bind_param(): Number of variables doesn’t match number of parameters in prepared statement

actualmente tengo un nuevo error, resulta cuando ingreso a los links de las ID’S de mis productos por ejemplo:

localhost/producto.php?id=10

Me lanza el siguiente error:

Warning: mysqli_stmt::bind_param(): Number of variables doesn’t match
number of parameters in prepared statement in C:xampphtdocsappdatabasedb.php on line 20

Y no se muestra el producto seleccionado, se queda estancado en el mismo en todas las IDS que selecciono por ejemplo:

localhost/producto.php?id=10 | Mayonesa

localhost/producto.php?id=11 | Mayonesa

localhost/producto.php?id=12 | Mayonesa

En todas las ID’S me muestra el producto de Mayonesa en vez del suyo en la base de datos. Por ejemplo la ID: 11 le pertenece a bebida.

Si no me equivoco este error se produce en la función de SelectOne ubicada en mi DB.php pero necesito insertar los JOINS y la única manera que consigo es esta, sin embargo me lanza el error.

El error se produce en esta línea:

if($table == "posts"){
      $sql = "SELECT t1.*, t2.name as tipo FROM posts AS t1 LEFT JOIN tipo as t2 ON (t1.tipo_id = t2.id)";

¿Alguien me puede ayudar a solucionarlo?

POSTS.PHP

if (isset($_GET('id'))){
    $id = $_GET('id');
    $post = selectOne($table, ('id' => $id));
}

DB.PHP

<?php

session_start();
require('connect.php');

function dd($value)
{
    echo "<pre>", print_r($value, true), "</pre>";
    die();
}


function executeQuery($sql, $data)
{
    global $conn;
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $stmt = $conn->prepare($sql);
    $values = array_values($data);
    $types = str_repeat('s', count($values));
    $stmt->bind_param($types, ...$values);
    $stmt->execute();
    return $stmt;
}


function selectAll($table, $conditions = ())
{
    global $conn;
    $sql = "SELECT * FROM $table";
            if($table == "posts"){
        $sql = "SELECT t1.*, t2.name as tipo FROM posts AS t1 LEFT JOIN tipo as t2 ON (t1.tipo_id = t2.id)";
        
        } 


    
    if (empty($conditions)) {
        $sql = $sql . " ORDER BY id DESC";
        $stmt = $conn->prepare($sql);
        $stmt->execute();
        $records = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        return $records;    
    } else {
        
        $i = 0;
        foreach ($conditions as $key => $value) {
            if ($i === 0){
                $sql = $sql . " WHERE $key=?";
                
            } else {
                $sql = $sql . " AND $key=?"; 
            }
            $i++;
        }
        
        $stmt = $conn->prepare($sql);
        $values = array_values($conditions);
        $types = str_repeat('s', count($values));
        $stmt->bind_param($types, $values);
        $stmt->execute();
        $records = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        return $records;
    }
}



function selectOne($table, $conditions)
{
   
    global $conn;
    $sql = "SELECT * FROM $table ";

        $i = 0;
                foreach ($conditions as $key => $value) {
                    
            if ($i === 0){
                $sql = $sql . " WHERE $key=?";
                
            } else {
               $sql = $sql . " AND $key=?"; 
            }
            $i++;
        }
    
        $sql = $sql . " LIMIT 1";
    
           if($table == "posts"){
    $sql = "SELECT t1.*, t2.name as tipo FROM posts AS t1 LEFT JOIN tipo as t2 ON (t1.tipo_id = t2.id)";
    
    } 
    
        $stmt = executeQuery($sql, $conditions);

        $records = $stmt->get_result()->fetch_assoc();
        return $records;
    
    }

function create($table, $data)
{
    global $conn;
    $sql = "INSERT INTO $table SET ";
      
    $i = 0;
    foreach ($data as $key => $value) {
            if ($i === 0){
                $sql = $sql . " $key=?";
                
            } else {
                $sql = $sql . ", $key=?"; 
            }
            $i++;
        }
    $stmt = executeQuery($sql, $data);
    $id = $stmt->insert_id;
    return $id;
    
}

function update($table, $id, $data)
{
    global $conn;
    $sql = "UPDATE $table SET ";
      
    $i = 0;
    foreach ($data as $key => $value) {
            if ($i === 0){
                $sql = $sql . " $key=?";
                
            } else {
                $sql = $sql . ", $key=?"; 
            }
            $i++;
        }
    
    $sql = $sql . " WHERE id=?";
    $data('id') = $id;
    $stmt = executeQuery($sql, $data);
    return $stmt->affected_rows;
    
}


function delete($table, $id)
{
    global $conn;
    $sql = "DELETE FROM $table WHERE id=?";
      
    $stmt = executeQuery($sql, ('id' => $id));
    return $stmt->affected_rows;
    
}


function getPostsByTopicId($anime_id){
    global $conn;
    $sql = "SELECT * FROM capitulos WHERE anime_id=?";
    $sql = $sql . " ORDER BY id DESC";
    $stmt = executeQuery($sql, ('anime_id' => $anime_id));
    $records = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    return $records;
}

user expectation – creating the correct password parameters for a site, with cc details stored

I am trying to think of the best requirements to set a password for a site. A credit card is stored on the site, but is only useful to the site owner. i.e. if someone else logged in, they wouldnt get much benefit.

Its actually a customer relationship management cloud software service.

So here are my options:

  1. min 6 character password – simple and easy, they can use their favorite password, and wont struggle to remember it.

  2. min 8 chars, 1 upper case, 1 number, 1 non-alphanumeric character – secure, but it gets annoying, and if you forget the password, its hard tor remember.

  3. min 6 chars, 1 number, 1 upper case – somewhere in between, a bit more secure, and a likely chance they can still enter their favorite password.

Thoughts?

sql – Select workorders (via parameters) and their children

I’ve mocked-up a query that will eventually be used to create a BIRT report (in IBM’s Maximo Asset Management platform).


The query/report will retrieve records as follows:

  1. Retrieve workorders based on the parameters that were selected by the user.
    • All of the parameters are optional.
    • For testing purposes, I’m using bind variables as parameters (Toad).
    • It doesn’t matter if the workorders are parents, children, or neither.
  2. Of the workorders that were retrieved, also select any children of those workorders.
    • There are only two levels to the parent/child hierarchy: parents and children (no grandchildren, etc.)

The output would look like this:

enter image description here

The blue boxes show examples of parents with children.


The query:

--short form definitions:
--wo   = workorder
--act  = actual (actual cost, actual date, etc.)
--pmtr = parameters

with 
wo_pmtr as (  --WOs filtered by parameters
select
    wonum,
    parent,
    hierarchypath,
    classstructureid,
    division,
    worktype,
    status, 
    trunc(actstart)  as actstart,
    trunc(actfinish) as actfinish,
    actlabcost,
    actmatcost,
    actservcost,
    acttoolcost,
    acttotalcost   
from
    workorder wo
where   
    --using bind variables as parameters in Toad
        (:wonum            is null     or wonum = :wonum)
    and (:division         is null     or division          = :division)
    and (:worktype         is null     or worktype          = :worktype)
    and (:status           is null     or status            = :status)
    and (:actstart         is null     or trunc(actstart)  >= :actstart)
    and (:actfinish        is null     or trunc(actfinish) <= :actfinish)

    --select where classification matches the parameter 
    --and select any child classifications too
    --(the classification hierarchy is not to be confused with the workorder hierarchy)
    and (:classstructureid is null     or (exists (select 1 from classancestor where ((ancestor = :classstructureid)) and (classstructureid=wo.classstructureid))))
)

select
    wo_pmtr.wonum,
    wo_pmtr.parent,
    wo_pmtr.hierarchypath,
    wo_pmtr.classstructureid,
    wo_pmtr.division,
    wo_pmtr.worktype,
    wo_pmtr.status, 
    wo_pmtr.actstart,
    wo_pmtr.actfinish,
    wo_pmtr.actlabcost,
    wo_pmtr.actmatcost,
    wo_pmtr.actservcost,
    wo_pmtr.acttoolcost,
    wo_pmtr.acttotalcost,
    coalesce(wo_pmtr.parent, wo_pmtr.wonum) parent_coalesced
from
    wo_pmtr      --WOs filtered by parameters
union            --union will remove duplicates (unlike union all)
select           --select children of the filtered WOs
    wo.wonum,
    wo.parent,
    wo.hierarchypath,
    wo.classstructureid,
    wo.division,
    wo.worktype,
    wo.status, 
    trunc(wo.actstart)  as actstart,
    trunc(wo.actfinish) as actfinish,
    wo.actlabcost,
    wo.actmatcost,
    wo.actservcost,
    wo.acttoolcost,
    wo.acttotalcost,
    coalesce(wo.parent, wo.wonum) parent_coalesced
from
    workorder wo  --select from the base workorder table *without* filtering by the parameters
left join
    wo_pmtr
    on wo.parent = wo_pmtr.wonum
where
    wo.parent        is not null   --where WO is a child
    and wo_pmtr.wonum is not null  --where WO is a child of the filtered WOs 
                                   --caution: some of those workorders might have already been selected via the parameters in the first query
                                   --we need to eliminate duplicates if they exist (via the union)
order by
    parent_coalesced, 
    hierarchypath

I’m new to reports and SQL queries like this. How can the query be improved?

  • For example: Is it a good practice to use UNION to eliminate duplicates?

query string – Is there a set of well-known tracking parameters besides utm_*?

I am collecting a large number of URLs. I am not responsible for the websites in question, and I want to remove tracking parameters that do not affect the content of the website. With the tracking parameters, it’s impossible to identify two URLs that should be considered equal.

For example, if I have the following links:

  1. http://example.com/blog/post1?utm_xyz=1234
  2. http://example.com/blog/post1?utm_xyz=5678
  3. http://example.net/viewblog?post_id=2&utm_xyz=9999

I want to convert to the equivalent canonical-type URLs:

  1. http://example.com/blog/post1
  2. http://example.com/blog/post1
  3. http://example.net/viewblog?post_id=2

The first two are for the same content, but have different tracking parameters. The last example illustrates why I can’t just remove all query parameters.

The most common of these are the utm_ ones, but I have also found:

  • Piwik: pk_campaign and pk_kwd
  • WebTrends: WT.nav, WT.mc_id
  • unknown, maybe Apple: campaign_id
  • Wikimedia: wprov
  • HootSuite: hootPostID

Is there a well-known list of these query parameters that I can safely remove?

(I am using the canonical URLs where they are supplied in the HTML metadata, but I want to use this approach when none is supplied.)

Extracting the component distribution parameters from a mixed-normal distribution (for n > 2 normal)

I’m trying to extract the distribution parameters of the sub-distributions which comprise a mixed normal distribution.

I’ll give my attempts so far.

First the simulated data:

MixedGaussiaData = Apply[Join, {RandomVariate[NormalDistribution[0, 2], 300], RandomVariate[NormalDistribution[0, 0.7], 500], RandomVariate[NormalDistribution[0, 0.4], 500], RandomVariate[NormalDistribution[0, 1], 200]}];

Which when plotted looks like this:

enter image description here

So we have four normal distributions with different $sigma$ values and different number of points, but all distributions have a common mean value $mu = 0$.

I define my $n$ mixed-normal distribution as:

NMixedGaussian[n_] := MixtureDistribution[Array[w, n], MapThread[NormalDistribution[#1, #2] &, {Array[m, n], Array[s, n]}]]

Then using FindDistributionParameters

FourMixedNormalMLE = FindDistributionParameters[MixedGaussiaData, NMixedGaussian[4], ParameterEstimator->{"MaximumLikelihood", PrecisionGoal->1, AccuracyGoal->1}]

If I plot the result, it looks pretty good:

enter image description here

However if we take a look at the results, they’re not that good when compared to the inputs of the simulation:

mMLE = Array[m, 4] /. FourMixedNormalMLE
sMLE = Array[s, 4] /. FourMixedNormalMLE
wMLE = Array[w, 4] /. FourMixedNormalMLE

{0.0284676, 0.00902554, 0.0930328, -0.470579}
{1.8648, 0.274301, 0.667947, 0.385259}
{0.237727, 0.192302, 0.475281, 0.0946906}

Second attempt:

I tried explicitly defining the Mixed-Gaussain function with ProbabilityDensity:

Clear[w, m, s, n];
NMixedGaussian[n_] := MixtureDistribution[Array[w, n], MapThread[NormalDistribution[#1, #2] &, {Array[m, n], Array[s, n]}]]

NMixGauss = NMixedGaussian[4];
NMixGaussPDF[z_] = FullSimplify[PDF[NMixGauss, z], DistributionParameterAssumptions[NMixGauss]]

NMixGaussPD = ProbabilityDistribution[NMixGaussPDF[z], {z, -Infinity, Infinity}, Assumptions -> DistributionParameterAssumptions[NMixGauss]]

FourMixedNormalPDFMLE = FindDistributionParameters[MixedGaussiaData, NMixGaussPD, ParameterEstimator->{"MaximumLikelihood", PrecisionGoal->1, AccuracyGoal->1}]

This makes it worse. I think the main issue might be initial values and constraints, but I’m not sure how to best implement this. Does anyone have any suggestions?

One thing I noticed is that the weights produced by FindDistributionParameters don’t seem to make sense. They sum to one, but none seem to correspond to weights defined by $1/sigma^{2}$ or $1/sigma_{rm{SE}}^{2}$


Addition:
What I’m trying to achieve is another way of performing a weighted mean. I could divide the simulated data up into chunks/bins, find the $mu$ and $sigma$ for each one and perform a weighted mean. I want to avoid binning if possible, hence this approach.

rest – Parsing complex object-like parameters via CLI arguments

Say we have an API that accepts a list of objects. Something like:

{
    "family": "Does",
    "contact_details": (
        {
            "name": "John",
            "email": "john@example.com"
        },
        {
            "name": "Jane",
            "email": "jane@example.com"
        }
    )
}

Say you then wanted to add a CLI for this, how would one structure the CLI parameters? The API is a nested API, but CLI arguments are by design flat.

I can think of two patterns, neither of which I like:

  1. Expose a new CLI to create these nested entries, and then use those to create the top-level object:

    $ foo contact create --name "John" --email "john@example.com"
    f53539be-205c-11eb-adc1-0242ac120002
    $ foo family create --name "Does" --contact f53539be-205c-11eb-adc1-0242ac120002
    

    I think this could work quite nicely if the API was well designed and allowed creation of these things as separate resources. Without that though, you’d have to somehow cache these fake resource locally, which sounds icky.

  2. Use CSV-style key-value pairs:

    $ foo family create --name "Does" --contact name=John,email=john@example.com
    

    This is hard to document and hard to use (no easy auto-completion, for one), particularly as the complexity of the object in the list grow.

Are there any other designs common across *nix-style CLIs that I’m missing?

graphics3d – Plotting 3D region depending on 2 parameters with constraints

$$textbf{Parameters}:quad theta,alpha,beta,gamma.$$
$$textbf{Conditions on parameters}:quad 0<theta<1,quad 1leq beta leq infty.$$
$$textbf{More constraints:}quad begin{cases}
4theta+frac{2}{beta}theta<1,\
6theta-frac{2}{beta}theta<1.\
end{cases} $$

$$textbf{Region to be plotted}:left(frac{1}{1-2theta-frac{theta}{beta}},frac{1}{1-2theta-frac{theta(beta-1)}{beta}},frac{1}{3theta}right) $$

Use RegionFunction and replace to 5 or other finite number.

ParametricPlot3D({1/(1 - 2*θ - θ/β), 
  1/(1 - 2*θ - (θ*(β - 1))/β), 
  1/(3*θ)}, {θ, 0, 1}, {β, 1, 5}, 
 RegionFunction -> 
  Function({θ, β}, 
   4 θ + 2/β < 1 && 6 θ - 2/β < 1))

Robots.txt disallow url only if it has parameters?

Take for example

/about?param1=blah
/contact?param1=bleh&param2=bluh

But allow

/about
/contact

Is that possible? Would disallowing /about?* work?