问:
Get subgraph of shortest path between n nodes
I have an unweighted graph and I want to get a subgraph that has just the nodes and edges that contain the shortest paths between n known nodes.  In this case 3 nodes (11, 29, & 13 are the names).

Question

How can I get a subgraph of shortest path between n nodes in R?

MWE

```<code>library(ggraph)
library(igraph)

hs <- highschool[highschool$year == '1958',]
set.seed(11)
graph <- graph_from_data_frame(hs[sample.int(nrow(hs), 60),])

# plot using ggraph
ggraph(graph, layout = 'kk') +
    geom_edge_fan() +
    geom_node_text(aes(label = name))
</code>```

Desired Output

The desired output would be the following green subgraph (Or close, I'm eyeballing the graph above and visually picking out what would be the subgraph) ignoring/removing the other nodes and edges.

答:
You need a matrix of shortest paths to then create a sub-graph using a union of all edges belonging to those paths.

Let key vertices be those vertices between which your desired sub-graph appears. You say you have three such key vertices.

Consider that the shortest path between any i and j of them is unlist(shortest_paths(g, i, j, mode="all", weights=NULL)$vpath). You'd want to list all i-j combinations (1-2, 1-3, 2-3 in your case) of your key-verticies, and then list all vertices that appear on the paths between them. Sometime, surely, the same vertices appear on the shortest paths of more than one of your ij-pairs (See betweenness centrality). Your desired subgraph should include only these vertices, which you can give to induced_subgraph().

Then arises another interesting problem. Not all edges between your choosen vertices are part of your shortest paths. I'm not sure about what you desire in your sub-graph, but I assume that you only want vertices and edges that are part of shortest paths. The manual for induced_subgraph() says that eids can be provided to filter sub-graphs on edges too, but I didn't get that to work. Comments on that are welcome if anyone cracks it. To create a subgraph with only edges and vertices actually in your shortest path, some surplus edges must be deleted.

Below is an example where some key verticies are chosen at random, the surplus-edge problem of subgraphs is visualized, and a proper shortert-paths-only subgraph is generated:

```<code>library(igraph)
N <- 40 # Number of vertices in a random network
E <- 70 # Number of edges in a random network
K <- 5  # Number of KEY vertices between which we are to calculate the
        # shortest paths and extract a sub-graph.

# Make a random network
g <- erdos.renyi.game(N, E, type="gnm", directed = FALSE, loops = FALSE)
V(g)$label <- NA
V(g)$color <- "white"
V(g)$size <- 8
E(g)$color <- "gray"

# Choose some random verteces and mark them as KEY vertices
key_vertices <- sample(1:N, 5)
g <- g %>% set_vertex_attr("color", index=key_vertices, value="red")
g <- g %>% set_vertex_attr("size", index=key_vertices, value=12)

# Find shortest paths between two vertices in vector x:
get_path <- function(x){
  # Get atomic vector of two key verteces and return their shortest path as vector.
  i <- x[1]; j <- x[2]
  # Check distance to see if any verticy is outside component. No possible
  # connection will return infinate distance:
  if(distances(g,i,j) == Inf){
    path <- c()
  } else {
    path <- unlist(shortest_paths(g, i, j, mode="all", weights=NULL)$vpath)
  }
}

# List pairs of key vertices between which we need the shortest path
key_el <- expand.grid(key_vertices, key_vertices)
key_el <- key_el[key_el$Var1 != key_el$Var2,]

# Get all shortest paths between each pair of key_vertices:
paths <- apply(key_el, 1, get_path)

# These are the vertices BETWEEN key vertices - ON the shortest paths between them:
path_vertices <- setdiff(unique(unlist(paths)), key_vertices)
g <- g %>% set_vertex_attr("color", index=path_vertices, value="gray")

# Mark all edges of a shortest path
mark_edges <- function(path, edges=c()){
  # Get a vector of id:s of connected vertices, find edge-id:s of all edges between them.
  for(n in 1:(length(path)-1)){
    i <- path[n]
    j <- path[1+n]
    edge <- get.edge.ids(g, c(i,j), directed = TRUE, error=FALSE, multi=FALSE)
    edges <- c(edges, edge)
  }
  # Return all edges in this path
  (edges)
}

# Find all edges that are part of the shortest paths between key vertices
key_edges <- lapply(paths, function(x) if(length(x) > 1){mark_edges(x)})
key_edges <- unique(unlist(key_edges))
g <- g %>% set_edge_attr("color", index=key_edges, value="green")

# This now shoes the full graph and the sub-graph which will be created
plot(g)

# Create sub-graph:
sg_vertices <- sort(union(key_vertices, path_vertices))
unclean_sg <- induced_subgraph(g, sg_vertices)
# Note that it is essential to provide both a verticy AND an edge-index for the
# subgraph since edges between included vertices do not have to be part of the
# calculated shortest path. I never used it before, but eids=key_edges given
# to induced_subgraph() should work (even though it didn't for me just now).

# See the problem here:
plot(unclean_sg)

# Kill edges of the sub-graph that were not part of shortest paths of the mother
# graph:
sg <- delete.edges(unclean_sg, which(E(unclean_sg)$color=="gray"))

# Plot a comparison:
l <-layout.auto(g)
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
plot(g, layout=l)
plot(unclean_sg, layout=l[sg_vertices,])  # cut l to keep same layout in subgraph
plot(sg, layout=l[sg_vertices,])          # cut l to keep same layout in subgraph
</code>```

Body:
I have an unweighted graph and I want to get a subgraph that has just the nodes and edges that contain the shortest paths between n known nodes.  In this case 3 nodes (11, 29, & 13 are the names).

Question

How can I get a subgraph of shortest path between n nodes in R?

MWE

library(ggraph)
library(igraph)

hs <- highschool[highschool$year == '1958',]
set.seed(11)
graph <- graph_from_data_frame(hs[sample.int(nrow(hs), 60),])

# plot using ggraph
ggraph(graph, layout = 'kk') +
    geom_edge_fan() +
    geom_node_text(aes(label = name))

Desired Output

The desired output would be the following green subgraph (Or close, I'm eyeballing the graph above and visually picking out what would be the subgraph) ignoring/removing the other nodes and edges.

Body:
You need a matrix of shortest paths to then create a sub-graph using a union of all edges belonging to those paths.

Let key vertices be those vertices between which your desired sub-graph appears. You say you have three such key vertices.

Consider that the shortest path between any i and j of them is unlist(shortest_paths(g, i, j, mode="all", weights=NULL)$vpath). You'd want to list all i-j combinations (1-2, 1-3, 2-3 in your case) of your key-verticies, and then list all vertices that appear on the paths between them. Sometime, surely, the same vertices appear on the shortest paths of more than one of your ij-pairs (See betweenness centrality). Your desired subgraph should include only these vertices, which you can give to induced_subgraph().

Then arises another interesting problem. Not all edges between your choosen vertices are part of your shortest paths. I'm not sure about what you desire in your sub-graph, but I assume that you only want vertices and edges that are part of shortest paths. The manual for induced_subgraph() says that eids can be provided to filter sub-graphs on edges too, but I didn't get that to work. Comments on that are welcome if anyone cracks it. To create a subgraph with only edges and vertices actually in your shortest path, some surplus edges must be deleted.

Below is an example where some key verticies are chosen at random, the surplus-edge problem of subgraphs is visualized, and a proper shortert-paths-only subgraph is generated:

library(igraph)
N <- 40 # Number of vertices in a random network
E <- 70 # Number of edges in a random network
K <- 5  # Number of KEY vertices between which we are to calculate the
        # shortest paths and extract a sub-graph.

# Make a random network
g <- erdos.renyi.game(N, E, type="gnm", directed = FALSE, loops = FALSE)
V(g)$label <- NA
V(g)$color <- "white"
V(g)$size <- 8
E(g)$color <- "gray"

# Choose some random verteces and mark them as KEY vertices
key_vertices <- sample(1:N, 5)
g <- g %>% set_vertex_attr("color", index=key_vertices, value="red")
g <- g %>% set_vertex_attr("size", index=key_vertices, value=12)

# Find shortest paths between two vertices in vector x:
get_path <- function(x){
  # Get atomic vector of two key verteces and return their shortest path as vector.
  i <- x[1]; j <- x[2]
  # Check distance to see if any verticy is outside component. No possible
  # connection will return infinate distance:
  if(distances(g,i,j) == Inf){
    path <- c()
  } else {
    path <- unlist(shortest_paths(g, i, j, mode="all", weights=NULL)$vpath)
  }
}

# List pairs of key vertices between which we need the shortest path
key_el <- expand.grid(key_vertices, key_vertices)
key_el <- key_el[key_el$Var1 != key_el$Var2,]

# Get all shortest paths between each pair of key_vertices:
paths <- apply(key_el, 1, get_path)

# These are the vertices BETWEEN key vertices - ON the shortest paths between them:
path_vertices <- setdiff(unique(unlist(paths)), key_vertices)
g <- g %>% set_vertex_attr("color", index=path_vertices, value="gray")

# Mark all edges of a shortest path
mark_edges <- function(path, edges=c()){
  # Get a vector of id:s of connected vertices, find edge-id:s of all edges between them.
  for(n in 1:(length(path)-1)){
    i <- path[n]
    j <- path[1+n]
    edge <- get.edge.ids(g, c(i,j), directed = TRUE, error=FALSE, multi=FALSE)
    edges <- c(edges, edge)
  }
  # Return all edges in this path
  (edges)
}

# Find all edges that are part of the shortest paths between key vertices
key_edges <- lapply(paths, function(x) if(length(x) > 1){mark_edges(x)})
key_edges <- unique(unlist(key_edges))
g <- g %>% set_edge_attr("color", index=key_edges, value="green")

# This now shoes the full graph and the sub-graph which will be created
plot(g)

# Create sub-graph:
sg_vertices <- sort(union(key_vertices, path_vertices))
unclean_sg <- induced_subgraph(g, sg_vertices)
# Note that it is essential to provide both a verticy AND an edge-index for the
# subgraph since edges between included vertices do not have to be part of the
# calculated shortest path. I never used it before, but eids=key_edges given
# to induced_subgraph() should work (even though it didn't for me just now).

# See the problem here:
plot(unclean_sg)

# Kill edges of the sub-graph that were not part of shortest paths of the mother
# graph:
sg <- delete.edges(unclean_sg, which(E(unclean_sg)$color=="gray"))

# Plot a comparison:
l <-layout.auto(g)
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
plot(g, layout=l)
plot(unclean_sg, layout=l[sg_vertices,])  # cut l to keep same layout in subgraph
plot(sg, layout=l[sg_vertices,])          # cut l to keep same layout in subgraph


来源: stackexchange

问:
EF migration issue on one-to-one when related table references first
I have a 1:1 relationship between Companies and CompanyDemographics created like this:

```<code>public class Company
{
    public Company()
    {
        Contacts = new HashSet<Contact>();
    }

    [Key]
    public int CompanyId { get; set; }

    public string Name { get; set; }

    [ForeignKey("CompanyId")]
    public virtual CompanyDemographic Demographic { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

public class CompanyDemographic
{
    [Key]
    [ForeignKey("Company")]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }

    public int EmployeeCount { get; set; }
}
</code>```

The migration builds correctly and everything works.

I then added a reference from CompanyDemographic back to Company like this:

```<code>public class CompanyDemographic
{
    [Key]
    [ForeignKey("Company")]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }

    public int EmployeeCount { get; set; }

    // ADDING THIS
    [ForeignKey("CurrentProvider")]
    public int CurrentProviderCompanyId { get; set; }
    public virtual Company CurrentProvider { get; set; }
}
</code>```

When I go to add the migration, it looks like this:

```<code>public override void Up()
{
    DropForeignKey("dbo.Contacts", "CompanyId", "dbo.Companies");
    DropForeignKey("dbo.CompanyDemographics", "CompanyId", "dbo.Companies");
    DropPrimaryKey("dbo.Companies");
    AddColumn("dbo.CompanyDemographics", "CurrentProviderCompanyId", c => c.Int(nullable: false));
    AlterColumn("dbo.Companies", "CompanyId", c => c.Int(nullable: false));
    AddPrimaryKey("dbo.Companies", "CompanyId");
    CreateIndex("dbo.Companies", "CompanyId");
    CreateIndex("dbo.CompanyDemographics", "CurrentProviderCompanyId");
    AddForeignKey("dbo.CompanyDemographics", "CurrentProviderCompanyId", "dbo.Companies", "CompanyId", cascadeDelete: true);
    AddForeignKey("dbo.Contacts", "CompanyId", "dbo.Companies", "CompanyId", cascadeDelete: true);
    AddForeignKey("dbo.CompanyDemographics", "CompanyId", "dbo.Companies", "CompanyId");
}
</code>```

It's trying to drop all the keys and rebuild. How do I avoid this?

答:
Converting @Steve Greene comment into an answer:

Putting [InverseAttribute("Company")] on the Demographic property of Company (instead of ForeignKey) solved it!

```<code>[InverseAttribute("Company")]
public virtual CompanyDemographic Demographic { get; set; }
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I have a 1:1 relationship between Companies and CompanyDemographics created like this:

public class Company
{
    public Company()
    {
        Contacts = new HashSet<Contact>();
    }

    [Key]
    public int CompanyId { get; set; }

    public string Name { get; set; }

    [ForeignKey("CompanyId")]
    public virtual CompanyDemographic Demographic { get; set; }

    public virtual ICollection<Contact> Contacts { get; set; }
}

public class CompanyDemographic
{
    [Key]
    [ForeignKey("Company")]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }

    public int EmployeeCount { get; set; }
}

The migration builds correctly and everything works.

I then added a reference from CompanyDemographic back to Company like this:

public class CompanyDemographic
{
    [Key]
    [ForeignKey("Company")]
    public int CompanyId { get; set; }
    public virtual Company Company { get; set; }

    public int EmployeeCount { get; set; }

    // ADDING THIS
    [ForeignKey("CurrentProvider")]
    public int CurrentProviderCompanyId { get; set; }
    public virtual Company CurrentProvider { get; set; }
}

When I go to add the migration, it looks like this:

public override void Up()
{
    DropForeignKey("dbo.Contacts", "CompanyId", "dbo.Companies");
    DropForeignKey("dbo.CompanyDemographics", "CompanyId", "dbo.Companies");
    DropPrimaryKey("dbo.Companies");
    AddColumn("dbo.CompanyDemographics", "CurrentProviderCompanyId", c => c.Int(nullable: false));
    AlterColumn("dbo.Companies", "CompanyId", c => c.Int(nullable: false));
    AddPrimaryKey("dbo.Companies", "CompanyId");
    CreateIndex("dbo.Companies", "CompanyId");
    CreateIndex("dbo.CompanyDemographics", "CurrentProviderCompanyId");
    AddForeignKey("dbo.CompanyDemographics", "CurrentProviderCompanyId", "dbo.Companies", "CompanyId", cascadeDelete: true);
    AddForeignKey("dbo.Contacts", "CompanyId", "dbo.Companies", "CompanyId", cascadeDelete: true);
    AddForeignKey("dbo.CompanyDemographics", "CompanyId", "dbo.Companies", "CompanyId");
}

It's trying to drop all the keys and rebuild. How do I avoid this?

Body:
Converting @Steve Greene comment into an answer:

Putting [InverseAttribute("Company")] on the Demographic property of Company (instead of ForeignKey) solved it!

[InverseAttribute("Company")]
public virtual CompanyDemographic Demographic { get; set; }


问:
CUDA tridiagonal solver function (cusparse)
In my CUDA code I am using cusparse<t>gtsv() function (more precisely, cusparseZgtsv and cusparseZgtsvStridedBatch ones).

In the documentaion it is said, that this function solves the equation A*x=alpha *B. My question is - what is alpha? I didn't find it as an input parameter. I have no idea how to specify it. Is it always equals to 1?

答:
I performed some testing (solved some random systems of equations where tridiagonal matrices were always diagonally dominant and checked my solution using direct matrix by vector multiplication).
It looks like in the current version alpha = 1 always, so one can just ignore it. I suspect that it will be added as an input parameter in future releases.</p>


问:
GNUPLOT vs. VBA - where did STDERR go?
I am running Gnuplot in the confines of VBA and it works surprisingly well.  I am able to produce an entire book of about one hundred graphs using GNUPLOT and Word VBA.  (With Excel graphs, I could get maybe about four)

There is one small problem - STDERR disappears, or is not being created, when run under VBA.  No diagnostics.

Given the following small GNUPLOT script,

```<code>set key bmargin left horizontal Right noreverse enhanced autotitle box lt black linewidth 1.000 dashtype solid
set samples 800, 800
set title "Simple Plots"
set title  font ",20" norotate
DEBUG_TERM_HTIC = 119
DEBUG_TERM_VTIC = 119
plot [-30:20] sin(x*20)*atan(x)
</code>```

my VBA code writes it to a temporary file and attempts to run it.  VBA generates

```<code>"C:\temp\Gnuplot\bin\gnuplot.exe" C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err"
</code>```

Then runs it with the Windows Shell, invoked like so:

```<code>Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
</code>```

then

```<code>wsh.Run x, 0, True ' x contains the generated GNUPLOT expression
</code>```

GNUPLOT executes flawlessly.

In the GNUPLOT expression, the first item is the location of the GNUPLOT program, which on my system happens to be "C:\temp\Gnuplot\bin\gnuplot.exe".  The second file is the temporary generated in the official Microsoft location C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt.  Last is the location of STDERR, 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err" where the 2> thing indicates that this is STDERR, not the normal output STDOUT.

Now suppose I introduce a deliberate error into the GNUPLOT source, I would expect an error file written containing something like

```<code>scooby doo where are you?
^
"C:\Users\VVKozlov\AppData\Local\Temp\gnuEC55.txt", line 4: invalid command
</code>```

When executed with the usual CMD.EXE outside of VBA, the STDERR file is created as expected.

When executed in the confines of VBA using the Windows Shell, no STDERR file is created.

How could I get this STDERR file to be produced under VBA?

答:
CreateObject("WScript.Shell").Run executes a command line directly.

Output redirection (the 2> syntax you're using) is a feature of the cmd.exe Windows Command Processor.

What you want to do is either:

Execute cmd.exe with the arguments and redirection you want.

Use CreateObject("WScript.Shell").Exec instead, which gives you access to the input, output, and error streams directly. You would then need to read from the stream and write the contents to a file yourself within the script if you want them recorded to a file.

Title: GNUPLOT vs. VBA - where did STDERR go?

Body:
I am running Gnuplot in the confines of VBA and it works surprisingly well.  I am able to produce an entire book of about one hundred graphs using GNUPLOT and Word VBA.  (With Excel graphs, I could get maybe about four)

There is one small problem - STDERR disappears, or is not being created, when run under VBA.  No diagnostics.

Given the following small GNUPLOT script,

set key bmargin left horizontal Right noreverse enhanced autotitle box lt black linewidth 1.000 dashtype solid
set samples 800, 800
set title "Simple Plots"
set title  font ",20" norotate
DEBUG_TERM_HTIC = 119
DEBUG_TERM_VTIC = 119
plot [-30:20] sin(x*20)*atan(x)

my VBA code writes it to a temporary file and attempts to run it.  VBA generates

"C:\temp\Gnuplot\bin\gnuplot.exe" C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err"

Then runs it with the Windows Shell, invoked like so:

Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")

then

wsh.Run x, 0, True ' x contains the generated GNUPLOT expression

GNUPLOT executes flawlessly.

In the GNUPLOT expression, the first item is the location of the GNUPLOT program, which on my system happens to be "C:\temp\Gnuplot\bin\gnuplot.exe".  The second file is the temporary generated in the official Microsoft location C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E0.txt.  Last is the location of STDERR, 2>"C:\Users\VVKOZLOV\AppData\Local\Temp\gnuA5E2.err" where the 2> thing indicates that this is STDERR, not the normal output STDOUT.

Now suppose I introduce a deliberate error into the GNUPLOT source, I would expect an error file written containing something like

scooby doo where are you?
^
"C:\Users\VVKozlov\AppData\Local\Temp\gnuEC55.txt", line 4: invalid command

When executed with the usual CMD.EXE outside of VBA, the STDERR file is created as expected.

When executed in the confines of VBA using the Windows Shell, no STDERR file is created.

How could I get this STDERR file to be produced under VBA?


问:
WHERE clause overwriting field value
The following query accurately returns the value w.price however w.time is given as 2017-11-23 15:12:00 which is not the correct value from the row returned. However, it consistently matches the WHERE time >= clause. What is causing this to happen?

```<code>SELECT
    history.pair_id,
    MIN(history.price) as all_time_low,
    history.time as all_time_low_time,
    w.price as one_week_price,
    w.time as one_week_time
    FROM ep_ex_waex history

INNER JOIN (
    SELECT MIN(price) as price, time, pair_id
    FROM ep_ex_waex
    WHERE pair_id = 2
    AND time >= '2017-11-23 15:12:00'
) as w ON w.pair_id = history.pair_id
</code>```

Result

```<code>+---------+--------------+---------------------+----------------+---------------------+
| pair_id | all_time_low | all_time_low_time   | one_week_price | one_week_time       |
+---------+--------------+---------------------+----------------+---------------------+
| 2       | 392.3        | 2017-11-23 12:11:00 | 396.77         | 2017-11-23 15:12:00 |
+---------+--------------+---------------------+----------------+---------------------+
</code>```

Not the column all_time_low_time is correct.

ep_ex_waex structure

```<code>CREATE TABLE `ep_ex_waex` (
  `id` int(11) NOT NULL,
  `pair_id` int(11) DEFAULT NULL,
  `price` double NOT NULL,
  `volume` double NOT NULL,
  `time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
</code>```

答:
Perhaps this mod will focus the result, using a WHERE to locate the price based on the pair_id and MIN.

```<code>SELECT price, time, pair_id
   FROM  ep_ex_waex ep
   WHERE pair_id = 2
   AND time >= '2017-11-23 15:12:00'
   AND price = (SELECT min(price) FROM ep_ex_waex WHERE pair_id=ep.pair_id);
</code>```

Your full query would look like this:

```<code>SELECT
  history.pair_id,
  MIN(history.price) as all_time_low,
  history.time as all_time_low_time,
  w.price as one_week_price,
  w.time as one_week_time
  FROM ep_ex_waex history

INNER JOIN (
  SELECT price, time, pair_id
  FROM ep_ex_waex ep
  WHERE pair_id = 2
  AND time >= '2017-11-23 15:12:00'
  AND price = (SELECT MIN(price) FROM ep_ex_waex eps WHERE eps.pair_id=ep.pair_id)
) as w ON w.pair_id = history.pair_id;
</code>```

It could probably be optimized a lot to not use so many subqueris, but hopefully you get the idea.

Good luck.

=== TEST CASE ===
Data used:

```<code>+-------+---------------------+---------+
| price | time                | pair_id |
+-------+---------------------+---------+
|  1.29 | 2017-11-23 15:12:00 |       2 |
|  1.19 | 2017-11-24 15:12:00 |       2 |
|  1.79 | 2017-11-25 15:12:00 |       2 |
+-------+---------------------+---------+
</code>```

Query:

```<code>mysql-sql>     SELECT price, time, pair_id
        FROM ep_ex_waex ep
        WHERE pair_id = 2
        AND time >= '2017-11-23 15:12:00'
        AND price = (SELECT MIN(price) FROM ep_ex_waex eps WHERE eps.pair_id=ep.pair_id);

+-------+---------------------+---------+
| price | time                | pair_id |
+-------+---------------------+---------+
|  1.19 | 2017-11-24 15:12:00 |       2 |
+-------+---------------------+---------+
</code>```

That looks right to me, found the middle record, lowest price, and matching date.  Break your query down into segments and see if you can get it working.

Title: WHERE clause overwriting field value

Body:
The following query accurately returns the value w.price however w.time is given as 2017-11-23 15:12:00 which is not the correct value from the row returned. However, it consistently matches the WHERE time >= clause. What is causing this to happen?

SELECT
    history.pair_id,
    MIN(history.price) as all_time_low,
    history.time as all_time_low_time,
    w.price as one_week_price,
    w.time as one_week_time
    FROM ep_ex_waex history

INNER JOIN (
    SELECT MIN(price) as price, time, pair_id
    FROM ep_ex_waex
    WHERE pair_id = 2
    AND time >= '2017-11-23 15:12:00'
) as w ON w.pair_id = history.pair_id

Result

+---------+--------------+---------------------+----------------+---------------------+
| pair_id | all_time_low | all_time_low_time   | one_week_price | one_week_time       |
+---------+--------------+---------------------+----------------+---------------------+
| 2       | 392.3        | 2017-11-23 12:11:00 | 396.77         | 2017-11-23 15:12:00 |
+---------+--------------+---------------------+----------------+---------------------+

Not the column all_time_low_time is correct.

ep_ex_waex structure

CREATE TABLE `ep_ex_waex` (
  `id` int(11) NOT NULL,
  `pair_id` int(11) DEFAULT NULL,
  `price` double NOT NULL,
  `volume` double NOT NULL,
  `time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Body:
Perhaps this mod will focus the result, using a WHERE to locate the price based on the pair_id and MIN.

SELECT price, time, pair_id
   FROM  ep_ex_waex ep
   WHERE pair_id = 2
   AND time >= '2017-11-23 15:12:00'
   AND price = (SELECT min(price) FROM ep_ex_waex WHERE pair_id=ep.pair_id);

Your full query would look like this:

SELECT
  history.pair_id,
  MIN(history.price) as all_time_low,
  history.time as all_time_low_time,
  w.price as one_week_price,
  w.time as one_week_time
  FROM ep_ex_waex history

INNER JOIN (
  SELECT price, time, pair_id
  FROM ep_ex_waex ep
  WHERE pair_id = 2
  AND time >= '2017-11-23 15:12:00'
  AND price = (SELECT MIN(price) FROM ep_ex_waex eps WHERE eps.pair_id=ep.pair_id)
) as w ON w.pair_id = history.pair_id;

It could probably be optimized a lot to not use so many subqueris, but hopefully you get the idea.

Good luck.

=== TEST CASE ===
Data used:

+-------+---------------------+---------+
| price | time                | pair_id |
+-------+---------------------+---------+
|  1.29 | 2017-11-23 15:12:00 |       2 |
|  1.19 | 2017-11-24 15:12:00 |       2 |
|  1.79 | 2017-11-25 15:12:00 |       2 |
+-------+---------------------+---------+

Query:

mysql-sql>     SELECT price, time, pair_id
        FROM ep_ex_waex ep
        WHERE pair_id = 2
        AND time >= '2017-11-23 15:12:00'
        AND price = (SELECT MIN(price) FROM ep_ex_waex eps WHERE eps.pair_id=ep.pair_id);

+-------+---------------------+---------+
| price | time                | pair_id |
+-------+---------------------+---------+
|  1.19 | 2017-11-24 15:12:00 |       2 |
+-------+---------------------+---------+

That looks right to me, found the middle record, lowest price, and matching date.  Break your query down into segments and see if you can get it working.


问:
Object oriented coding in a multi threaded request environment - PHP
I am writing a web application in an object oriented design. This application would be interacting with the database pretty often. A few regular operations are verifying a user's ACL permissions for the function/method requested, performing certain functions etc. In a nutshell, the database would be used a lot. So my question here is, if I do develop my application using OOP, and declare class level variables which would be used to set the input coming in, and if there is any parallel or concurrent request coming in from another user, would the input data be changed??

Would I have to do something separate to make sure that the application is multi-threaded and the input coming in be not changed until the process isn't finished??

ex:

```<code>class myProces{
var $input1;
var $input2;

    function process1($ip1, $ip2){
      $this->input1 = $ip1;
      $this->input2 = $ip2;
      $this->getDataDB();
    }

    function getDataDB(){
     //do some database activity with the class level variables;
     // I would pass the values in the class level variables;
    $query = "select column from table where col1 = $this->input1 and col2= $this->input2";

    mysql_query($query);

    return something;
    }

}
</code>```

Now if I have two users hitting my application at the same time, and make a call to the functions in this class

user1:
$obj = new myProces();
$obj->process1(1,2);

user2:
$obj = new myProces();
$obj->process1(5,6);

Now if I do have class level variables, would they have changed values when concurrent requests come in?? Would PHP doing any kind of handling for multi threading? I am not sure if Apache can act as a message queue, where requests can be queued.

Can anybody explain if OOP for web applications with heavy number of users is good or if any kind of multithreading has to be done by developers??

答:
This isn't a problem you have to worry about. Each connection to your web server spawns a totally separate instance of the PHP interpreter, with totally separate memory and resource handles. No objects in one will be affected by the other, no database connections in one will be affected by the other. Your class properties in one process are not ever modified by a request in another process.

Many of the top sites on the web run on Apache and PHP, with hundreds of concurrent request happening simultaneously all day long, and they do not have to write any special code to handle it.

ContentLicense: CC BY-SA 2.5

Body:
I am writing a web application in an object oriented design. This application would be interacting with the database pretty often. A few regular operations are verifying a user's ACL permissions for the function/method requested, performing certain functions etc. In a nutshell, the database would be used a lot. So my question here is, if I do develop my application using OOP, and declare class level variables which would be used to set the input coming in, and if there is any parallel or concurrent request coming in from another user, would the input data be changed??

Would I have to do something separate to make sure that the application is multi-threaded and the input coming in be not changed until the process isn't finished??

ex:

class myProces{
var $input1;
var $input2;

    function process1($ip1, $ip2){
      $this->input1 = $ip1;
      $this->input2 = $ip2;
      $this->getDataDB();
    }

    function getDataDB(){
     //do some database activity with the class level variables;
     // I would pass the values in the class level variables;
    $query = "select column from table where col1 = $this->input1 and col2= $this->input2";

    mysql_query($query);

    return something;
    }

}

Now if I have two users hitting my application at the same time, and make a call to the functions in this class

user1:
$obj = new myProces();
$obj->process1(1,2);

user2:
$obj = new myProces();
$obj->process1(5,6);

Now if I do have class level variables, would they have changed values when concurrent requests come in?? Would PHP doing any kind of handling for multi threading? I am not sure if Apache can act as a message queue, where requests can be queued.

Can anybody explain if OOP for web applications with heavy number of users is good or if any kind of multithreading has to be done by developers??


问:
How to time javascript actions so that they happen at the right order
I am trying to figure out how to time this for statement so it happens every second or so. What ends up happening is that the x prints 5 for all logs because the for loop is looping before the Timeout happens. How can I time the loops so every iteration happens after the setTimeout finishes.

for (x = 0; x < 5; x++) {
  var wait = setTimeout( function() {
    console.log(x,"x");
  }, 800);
}```

答:
Other answers here are of course correct.

But going forward into the future async code is much easier using async / await.

So below is a simple example,.. It initially looks longer, due to utility function delay, but as your program gets larger using async / await will make your code much easier to follow.

Another advantage here too, is only 1 setTimeout is created,.  So potentially more resource friendly.  You could also achieve using 1 setTimeout without async / await but would require chaining the setTimeout's making the code even harder to follow.

// utility function do delay,
// can be used again..
function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
}

//await can only be called from async function.
//so lets just create run function to get things started.

async function run () {
  for (let x = 0; x < 5; x++) {
    await delay(800);
    console.log(x,"x");
  }
}

//lets get things started..
run ();```


问:
Overflow Error with VBA Code Recommendations
I am trying to run a macro. The macro looks in each row in column A and if the value is greater than 0 it will copy a range of cells from the same row (M:BT) and paste and transpose that range in the cell in column K of the same row. The code below works but the number of rows change and can be a lot. I need it to loop through until no more data can be found in column A. Keep in mind there will be empty rows. As I said before my code works with a small sample 100 rows but when I did one for like 65,000 rows it give me an

Overflow error

Any ideas how to fix this?

```<code>Sub Macro1()
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+w
'
Range("K1").Select
ActiveCell.FormulaR1C1 = "DATE"
Range("L1").Select
ActiveCell.FormulaR1C1 = "DAYS"
Columns("BU:EB").Select
Selection.Delete Shift:=xlToLeft
Columns("EC:IR").Select
Selection.Delete Shift:=xlToLeft
With ActiveSheet
    lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

Dim AddRows As Integer: AddRows = 59

Dim i As Integer: i = lastrow

Do While i <> 1
    Rows(i & ":" & i + AddRows - 1).Insert
    i = i - 1
Loop

ScreenUpdating = True
Rows("2:60").Select
Selection.Delete Shift:=xlUp
Range("A1").Select

Dim x As Integer, a As Integer
a = Cells(Rows.Count, 1).End(xlUp).Row

For x = 2 To a
If Cells(i, 1) > 0 Then
Range(Cells(x, 13), Cells(x, 72)).Select
Selection.Copy
Cells(x, 11).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=True, Transpose:=True
End If
Next x
End Sub
</code>```

答:
Integers are not "big enough" to hold your large number. Use Long instead of Integer.

```<code>Dim x As Long, a As Long
</code>```

See https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/data-type-summary Integer data type is signed 2 bytes and can therefore only hold from -32768 to + 32767

Body:
I am trying to run a macro. The macro looks in each row in column A and if the value is greater than 0 it will copy a range of cells from the same row (M:BT) and paste and transpose that range in the cell in column K of the same row. The code below works but the number of rows change and can be a lot. I need it to loop through until no more data can be found in column A. Keep in mind there will be empty rows. As I said before my code works with a small sample 100 rows but when I did one for like 65,000 rows it give me an

Overflow error

Any ideas how to fix this?

Sub Macro1()
'
' Macro1 Macro
'
' Keyboard Shortcut: Ctrl+w
'
Range("K1").Select
ActiveCell.FormulaR1C1 = "DATE"
Range("L1").Select
ActiveCell.FormulaR1C1 = "DAYS"
Columns("BU:EB").Select
Selection.Delete Shift:=xlToLeft
Columns("EC:IR").Select
Selection.Delete Shift:=xlToLeft
With ActiveSheet
    lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With

Dim AddRows As Integer: AddRows = 59

Dim i As Integer: i = lastrow

Do While i <> 1
    Rows(i & ":" & i + AddRows - 1).Insert
    i = i - 1
Loop

ScreenUpdating = True
Rows("2:60").Select
Selection.Delete Shift:=xlUp
Range("A1").Select

Dim x As Integer, a As Integer
a = Cells(Rows.Count, 1).End(xlUp).Row

For x = 2 To a
If Cells(i, 1) > 0 Then
Range(Cells(x, 13), Cells(x, 72)).Select
Selection.Copy
Cells(x, 11).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=True, Transpose:=True
End If
Next x
End Sub

Body:
Integers are not "big enough" to hold your large number. Use Long instead of Integer.

Dim x As Long, a As Long

See https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/data-type-summary Integer data type is signed 2 bytes and can therefore only hold from -32768 to + 32767


问:
How do I send data from activity A to activity B without using firebase?
I am currently working on an "Order food from home" restaurant app.
What I am trying to do is to send the quantity of a product (a bottle of CocaCola for example) from the activity that includes only the juice to the "Shopping Cart" activity where I will calculate the price and then show both the quantity and the total price of the product.

My problem is that I can't really figure out how to send information from activity A to activity B.

If possible, I would like doing that without using a database. (Through intents for example)
This code shows on the activity with the juice the quantity of CocaCola's the customer wishes to buy. I want to send this quantity in the shoppingCart activity.

Code:

```<code>public void displayCantitateCocaCola(int number){
    TextView quantityText = (TextView) findViewById(R.id.cantitateCola);
    quantityText.setText("" + number);
}
</code>```

So, if the above method's display is 3, I want to get that value in the shopping cart activity.

答:
did you try to send your data inside intent?
when you are moving from activity a to b use this answer:
https://stackoverflow.com/a/2091482/6565331
   Fast answer:
Activity A:

```<code>    Intent i = new Intent(A.this,B.class)
i.putExtra("key", YOUR VALUE);
Startactivity(i)
</code>```

Activity B on create:

```<code>Int value=0;
 Intent intent= getIntent();
 Bundle b = intent.getExtras();
 if(b!=null) {
Int value =(Int) b.get("key");
}
</code>```

Body:
I am currently working on an "Order food from home" restaurant app.
What I am trying to do is to send the quantity of a product (a bottle of CocaCola for example) from the activity that includes only the juice to the "Shopping Cart" activity where I will calculate the price and then show both the quantity and the total price of the product.

My problem is that I can't really figure out how to send information from activity A to activity B.

If possible, I would like doing that without using a database. (Through intents for example)
This code shows on the activity with the juice the quantity of CocaCola's the customer wishes to buy. I want to send this quantity in the shoppingCart activity.

Code:

public void displayCantitateCocaCola(int number){
    TextView quantityText = (TextView) findViewById(R.id.cantitateCola);
    quantityText.setText("" + number);
}

So, if the above method's display is 3, I want to get that value in the shopping cart activity.

Body:
did you try to send your data inside intent?
when you are moving from activity a to b use this answer:
https://stackoverflow.com/a/2091482/6565331
   Fast answer:
Activity A:

    Intent i = new Intent(A.this,B.class)
i.putExtra("key", YOUR VALUE);
Startactivity(i)

Activity B on create:

Int value=0;
 Intent intent= getIntent();
 Bundle b = intent.getExtras();
 if(b!=null) {
Int value =(Int) b.get("key");
}


问:
Error with Date format converting to numeric
I am getting an error with dates when runnin a function in the PMwR package. It seems my dates are not numeric, however, converting them to numeric yields NAs.

Best wishes,

```<code>> pl(DaxH1)
Error in Math.data.frame(amount) :
  non-numeric variable in data frame: timestampprice

> dput(head(DaxH1))
structure(list(timestamp = c("2008-01-14 11:00:59", "2008-01-14 13:00:59",
"2008-01-16 17:00:59", "2008-01-17 11:00:59", "2008-01-22 16:00:59",
"2008-01-23 09:07:59"), amount = c(19L, -19L, 20L, -20L, 22L,
-22L), price = c("7735.37", "7741.90", "7485.11", "7528.99",
"6651.13", "6769.17")), .Names = c("timestamp", "amount", "price"
), row.names = c(NA, 6L), class = "data.frame")

> summary(DaxH1)
  timestamp             amount       price
 Length:624         Min.   :-51   Length:624
 Class :character   1st Qu.:-32   Class :character
 Mode  :character   Median :  0   Mode  :character
                    Mean   :  0
                    3rd Qu.: 32
                    Max.   : 51
</code>```

答:
Your data is in a character format. Convert it to time format then you can convert to numeric. </p>

```<code>> as.numeric(as.POSIXct(xx$timestamp ))
[1] 1200337259 1200344459 1200531659 1200596459 1201046459 1201108079
</code>```

Body:
I am getting an error with dates when runnin a function in the PMwR package. It seems my dates are not numeric, however, converting them to numeric yields NAs.

Best wishes,

> pl(DaxH1)
Error in Math.data.frame(amount) :
  non-numeric variable in data frame: timestampprice

> dput(head(DaxH1))
structure(list(timestamp = c("2008-01-14 11:00:59", "2008-01-14 13:00:59",
"2008-01-16 17:00:59", "2008-01-17 11:00:59", "2008-01-22 16:00:59",
"2008-01-23 09:07:59"), amount = c(19L, -19L, 20L, -20L, 22L,
-22L), price = c("7735.37", "7741.90", "7485.11", "7528.99",
"6651.13", "6769.17")), .Names = c("timestamp", "amount", "price"
), row.names = c(NA, 6L), class = "data.frame")

> summary(DaxH1)
  timestamp             amount       price
 Length:624         Min.   :-51   Length:624
 Class :character   1st Qu.:-32   Class :character
 Mode  :character   Median :  0   Mode  :character
                    Mean   :  0
                    3rd Qu.: 32
                    Max.   : 51

Body:
Your data is in a character format. Convert it to time format then you can convert to numeric.

> as.numeric(as.POSIXct(xx$timestamp ))
[1] 1200337259 1200344459 1200531659 1200596459 1201046459 1201108079


问:
Transform a dataset
I want to transform an aggregated dataset into a new derived one with the individual instances that correspond to the initial aggregation.
I loaded the dataset Titanic from R and looked at its data frame. I see that the frequencies of each tuple occurrence are aggregated. (For example, 20 Female Adult Crew Members survived the crash). I wanted to rebuild the dataset by replacing each tuple with the corresponding unaggregated tuples (e.g. 20 times the tuple "Crew, Female, Adult, Yes").
I know how to aggregate a dataset but I can not transform an already aggregated dataset. Any tip would be greatly appreciated.

```<code>library(dplyr)
library(purrr)
library(tidyr)

# keep data with frequency > 0
T = data.frame(Titanic, stringsAsFactors = F) %>% filter(Freq > 0)

tbl_df(T) %>%                           # tbl_df() only used to produce a more readable output (i.e. print only a few rows)
  mutate(id = map(Freq, ~ 1:.)) %>%     # create a vector of ids from 1 to Freq for each row
  unnest(id)                            # expand the vector

# # A tibble: 2,201 x 6
#    Class    Sex    Age Survived  Freq    id
#   <fctr> <fctr> <fctr>   <fctr> <dbl> <int>
# 1    3rd   Male  Child       No    35     1
# 2    3rd   Male  Child       No    35     2
# 3    3rd   Male  Child       No    35     3
# 4    3rd   Male  Child       No    35     4
# 5    3rd   Male  Child       No    35     5
# 6    3rd   Male  Child       No    35     6
# 7    3rd   Male  Child       No    35     7
# 8    3rd   Male  Child       No    35     8
# 9    3rd   Male  Child       No    35     9
# 10   3rd   Male  Child       No    35    10
# # ... with 2,191 more rows
</code>```

You can remove the id column if you want. I left it there just to make it easier to see how the process works.
You can also check that the number of rows of the new dataset is 2,201 which is equal to sum(T$Freq). So, as expected, the sum of frequencies of the original dataset is the number of rows of the new dataset.

Title: Transform a dataset

Body:
I want to transform an aggregated dataset into a new derived one with the individual instances that correspond to the initial aggregation.
I loaded the dataset Titanic from R and looked at its data frame. I see that the frequencies of each tuple occurrence are aggregated. (For example, 20 Female Adult Crew Members survived the crash). I wanted to rebuild the dataset by replacing each tuple with the corresponding unaggregated tuples (e.g. 20 times the tuple "Crew, Female, Adult, Yes").
I know how to aggregate a dataset but I can not transform an already aggregated dataset. Any tip would be greatly appreciated.

library(dplyr)
library(purrr)
library(tidyr)

# keep data with frequency > 0
T = data.frame(Titanic, stringsAsFactors = F) %>% filter(Freq > 0)

tbl_df(T) %>%                           # tbl_df() only used to produce a more readable output (i.e. print only a few rows)
  mutate(id = map(Freq, ~ 1:.)) %>%     # create a vector of ids from 1 to Freq for each row
  unnest(id)                            # expand the vector

# # A tibble: 2,201 x 6
#    Class    Sex    Age Survived  Freq    id
#   <fctr> <fctr> <fctr>   <fctr> <dbl> <int>
# 1    3rd   Male  Child       No    35     1
# 2    3rd   Male  Child       No    35     2
# 3    3rd   Male  Child       No    35     3
# 4    3rd   Male  Child       No    35     4
# 5    3rd   Male  Child       No    35     5
# 6    3rd   Male  Child       No    35     6
# 7    3rd   Male  Child       No    35     7
# 8    3rd   Male  Child       No    35     8
# 9    3rd   Male  Child       No    35     9
# 10   3rd   Male  Child       No    35    10
# # ... with 2,191 more rows

You can remove the id column if you want. I left it there just to make it easier to see how the process works.
You can also check that the number of rows of the new dataset is 2,201 which is equal to sum(T$Freq). So, as expected, the sum of frequencies of the original dataset is the number of rows of the new dataset.


问:
Rails search association
I am creating a simple search form in my Rails app and right now it lets me search a Pdform attribute. A pdform belongs to a user so there is a user_id in the pdform model.

How can I search a users first_name and have it bring up all of the pdforms that belong to them?

This is how I have it setup.

Routes

```<code>get '/pdforms/history', to: 'pdforms#history'
</code>```

Views

```<code><%= form_tag pdforms_history_path, :method => 'get' do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag 'Search', :name => nil %>
<% end %>
</code>```

Pdforms controller

```<code>def history
    @pdforms = Pdform.search(params[:search])
  end
</code>```

Pdform Model

```<code>def self.search(search)
  if search
    self.where("user.first_name like ?", "%#{search}%")
  else
    self.all
  end
end
</code>```

答:
I'm assuming an admin (as mentioned in your comment) should have a search capability whereas a regular user should just be able to see their own Pdforms.

So, perhaps your view could include something like:

```<code><% if is_admin? %>
  <%= form_tag pdforms_history_path, :method => 'get' do %>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag 'Search', :name => nil %>
  <% end %>
<% else %>
  <%= link_to 'List', pdforms_history_path %>
<% end %>
</code>```

And then your controller could do something like (borrowing liberally from AntonTkachov's answer):

```<code>def history
  if params[:search] and is_admin?
    @pdforms = self.joins(:user).where("users.first_name LIKE ? OR users.last_name LIKE ?", "%#{search}%", "%#{search}%")
  else
    @pdforms = Pdform.where(user: current_user)
  end
end
</code>```

NOTE: That whole is_admin? thing is just an example. You would need to make sure you actually have such a method/helper available - which I don't know if you do. Also, you should decide if you want to do is_admin? again in if params[:search] and is_admin?, just to make sure the user isn't monkeying around with the URL.

And, then you should have a views/pdforms/_history.html.erb that renders the @pdforms nicely. Like, perhaps, with each Pdform on a single row of a table.

Title: Rails search association

Body:
I am creating a simple search form in my Rails app and right now it lets me search a Pdform attribute. A pdform belongs to a user so there is a user_id in the pdform model.

How can I search a users first_name and have it bring up all of the pdforms that belong to them?

This is how I have it setup.

Routes

get '/pdforms/history', to: 'pdforms#history'

Views

<%= form_tag pdforms_history_path, :method => 'get' do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag 'Search', :name => nil %>
<% end %>

Pdforms controller

def history
    @pdforms = Pdform.search(params[:search])
  end

Pdform Model

def self.search(search)
  if search
    self.where("user.first_name like ?", "%#{search}%")
  else
    self.all
  end
end

Body:
I'm assuming an admin (as mentioned in your comment) should have a search capability whereas a regular user should just be able to see their own Pdforms.

So, perhaps your view could include something like:

<% if is_admin? %>
  <%= form_tag pdforms_history_path, :method => 'get' do %>
    <%= text_field_tag :search, params[:search] %>
    <%= submit_tag 'Search', :name => nil %>
  <% end %>
<% else %>
  <%= link_to 'List', pdforms_history_path %>
<% end %>

And then your controller could do something like (borrowing liberally from AntonTkachov's answer):

def history
  if params[:search] and is_admin?
    @pdforms = self.joins(:user).where("users.first_name LIKE ? OR users.last_name LIKE ?", "%#{search}%", "%#{search}%")
  else
    @pdforms = Pdform.where(user: current_user)
  end
end

NOTE: That whole is_admin? thing is just an example. You would need to make sure you actually have such a method/helper available - which I don't know if you do. Also, you should decide if you want to do is_admin? again in if params[:search] and is_admin?, just to make sure the user isn't monkeying around with the URL.

And, then you should have a views/pdforms/_history.html.erb that renders the @pdforms nicely. Like, perhaps, with each Pdform on a single row of a table.


问:
What is the right way to use lodash-es in Angular Universal?
Angular Universal server breaks when I replace my imports from lodash to lodash-es. But when I run ng serve, things are fine. I want to use lodash-es so I can cherry-pick lodash functions in my Angular SPA and shrink bundle size.

Steps I took: npm uninstalled lodash, npm installed lodash-es, and replaced my imports like this:

From: import { find as _find } from "lodash";

To: import { find as _find } from "lodash-es";

This is the server error I am getting:

```<code>/usr/src/app/node_modules/lodash-es/lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:599:28)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/src/app/dist/server.js:246:18)
</code>```

server.ts

```<code>import "zone.js/dist/zone-node";
import "reflect-metadata";
import { renderModuleFactory } from "@angular/platform-server";
import { enableProdMode } from "@angular/core";

import * as express from "express";
import * as minifyHTML from "express-minify-html";
import { join } from "path";
import { readFileSync } from "fs";

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), "dist");

// Our index.html we'll use as our template
const template = readFileSync(
  join(DIST_FOLDER, "browser", "index.html")
).toString();

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
  AppServerModuleNgFactory,
  LAZY_MODULE_MAP
} = require("./dist/server/main.bundle");

// Express Engine
import { ngExpressEngine } from "@nguniversal/express-engine";
// Import module map for lazy loading
import { provideModuleMap } from "@nguniversal/module-map-ngfactory-loader";

app.use(
  minifyHTML({
    override: true,
    exception_url: false,
    htmlMinifier: {
      removeComments: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeEmptyAttributes: true,
      minifyJS: true,
      minifyCSS: true
    }
  })
);

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
  "html",
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory
  })
);

app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));

/* - Example Express Rest API endpoints -
  app.get('/api/**', (req, res) => { });
*/

// Server static files from /browser
app.get(
  "*.*",
  express.static(join(DIST_FOLDER, "browser"), {
    maxAge: "1y"
  })
);

// ALl regular routes use the Universal engine
app.get("*", (req, res) => {
  res.render("index", { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});
</code>```

This is webpack.server.config.js (might be related?):

```<code>const path = require("path");
const webpack = require("webpack");
const nodeExternals = require("webpack-node-externals");

module.exports = {
  entry: { server: "./server.ts" },
  resolve: { extensions: [".ts", ".js"] },
  target: "node",
  externals: [nodeExternals()],
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js"
  },
  module: {
    rules: [{ test: /\.ts$/, loader: "ts-loader" }]
  },
  plugins: [
    new webpack.DefinePlugin({
      window: undefined,
      document: undefined
    }),
    new webpack.ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, "src"), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, "src")
    )
  ]
};
</code>```

答:
Angular 2+ is typescript .. so you need to install @types/lodash from npm using the command below

```<code>npm install --save @types/lodash
</code>```

then you need to import that in component like:

```<code>import * as lodash from 'lodash';
</code>```

you can use lodash like

```<code>lodash.find()  etc...
</code>```

Body:
Angular Universal server breaks when I replace my imports from lodash to lodash-es. But when I run ng serve, things are fine. I want to use lodash-es so I can cherry-pick lodash functions in my Angular SPA and shrink bundle size.

Steps I took: npm uninstalled lodash, npm installed lodash-es, and replaced my imports like this:

From: import { find as _find } from "lodash";

To: import { find as _find } from "lodash-es";

This is the server error I am getting:

/usr/src/app/node_modules/lodash-es/lodash.js:10
export { default as add } from './add.js';
^^^^^^
SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:599:28)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/src/app/dist/server.js:246:18)

server.ts

import "zone.js/dist/zone-node";
import "reflect-metadata";
import { renderModuleFactory } from "@angular/platform-server";
import { enableProdMode } from "@angular/core";

import * as express from "express";
import * as minifyHTML from "express-minify-html";
import { join } from "path";
import { readFileSync } from "fs";

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), "dist");

// Our index.html we'll use as our template
const template = readFileSync(
  join(DIST_FOLDER, "browser", "index.html")
).toString();

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
  AppServerModuleNgFactory,
  LAZY_MODULE_MAP
} = require("./dist/server/main.bundle");

// Express Engine
import { ngExpressEngine } from "@nguniversal/express-engine";
// Import module map for lazy loading
import { provideModuleMap } from "@nguniversal/module-map-ngfactory-loader";

app.use(
  minifyHTML({
    override: true,
    exception_url: false,
    htmlMinifier: {
      removeComments: true,
      collapseWhitespace: true,
      collapseBooleanAttributes: true,
      removeAttributeQuotes: true,
      removeEmptyAttributes: true,
      minifyJS: true,
      minifyCSS: true
    }
  })
);

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
  "html",
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory
  })
);

app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));

/* - Example Express Rest API endpoints -
  app.get('/api/**', (req, res) => { });
*/

// Server static files from /browser
app.get(
  "*.*",
  express.static(join(DIST_FOLDER, "browser"), {
    maxAge: "1y"
  })
);

// ALl regular routes use the Universal engine
app.get("*", (req, res) => {
  res.render("index", { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

This is webpack.server.config.js (might be related?):

const path = require("path");
const webpack = require("webpack");
const nodeExternals = require("webpack-node-externals");

module.exports = {
  entry: { server: "./server.ts" },
  resolve: { extensions: [".ts", ".js"] },
  target: "node",
  externals: [nodeExternals()],
  output: {
    path: path.join(__dirname, "dist"),
    filename: "[name].js"
  },
  module: {
    rules: [{ test: /\.ts$/, loader: "ts-loader" }]
  },
  plugins: [
    new webpack.DefinePlugin({
      window: undefined,
      document: undefined
    }),
    new webpack.ContextReplacementPlugin(
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, "src"), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, "src")
    )
  ]
};

Body:
Angular 2+ is typescript .. so you need to install @types/lodash from npm using the command below

npm install --save @types/lodash

then you need to import that in component like:

import * as lodash from 'lodash';

you can use lodash like

lodash.find()  etc...


问:
Need help translating this JQuery code back to raw Javascript
I'm currently having trouble understanding what's going on with this code

```<code> $("#table").on("click", ".plusRow", function(event){
            var name = this.getAttribute("table-data");
            tableData.addData(name, 0, 1);
            displayTable();
        });
</code>```

I understand that the first part should go something along the lines of

```<code>document.getElementById("table").addEventListener("click", function(event)
</code>```

but im having trouble understanding where the ".plusRow" class should go, is it added onto the eventlistener? or how would this code be better translated back to regular Javascript.

答:
This code snippets binds a listener on a single element (the table) and delegates it to its children which means that it will only run the event handler when it bubbles up to one or multiple elements that match the predicate (having a "plusRow" class).

With event delegation you could do:

```<code>let table = document.getElementById('table');
table.addEventListener('click', event => {
    const elem = event.target;
    if (elem.classList.contains('plusRow')) {
        const name = elem.getAttribute("table-data");
        tableData.addData(name, 0, 1);
        displayTable();
    }
});
</code>```

Here we have to keep in mind that this code will always run when a child of the table is clicked but will only update the table when the target matches the predicate.

Without using event delegation you could do the following which will have similar results but behaves quite differently:

```<code>let tableElem = document.getElementById('table');
// To keep this simple we assume there is only one button
let button = tableElem.getElementsByClassName('plusRow')[0];

button.addEventListener('click', event => {
    const name = event.currentTarget.getAttribute("table-data");
    tableData.addData(name, 0, 1);
    displayTable();
})
</code>```

This version will only ever run when the first child of the table with a class of "plusRow" is clicked. Please note that this is just an example because if there is no element with such class an exception will be raised when we try to bind the event listener.

Body:
I'm currently having trouble understanding what's going on with this code

 $("#table").on("click", ".plusRow", function(event){
            var name = this.getAttribute("table-data");
            tableData.addData(name, 0, 1);
            displayTable();
        });

I understand that the first part should go something along the lines of

document.getElementById("table").addEventListener("click", function(event)

but im having trouble understanding where the ".plusRow" class should go, is it added onto the eventlistener? or how would this code be better translated back to regular Javascript.

Body:
This code snippets binds a listener on a single element (the table) and delegates it to its children which means that it will only run the event handler when it bubbles up to one or multiple elements that match the predicate (having a "plusRow" class).

With event delegation you could do:

let table = document.getElementById('table');
table.addEventListener('click', event => {
    const elem = event.target;
    if (elem.classList.contains('plusRow')) {
        const name = elem.getAttribute("table-data");
        tableData.addData(name, 0, 1);
        displayTable();
    }
});

Here we have to keep in mind that this code will always run when a child of the table is clicked but will only update the table when the target matches the predicate.

Without using event delegation you could do the following which will have similar results but behaves quite differently:

let tableElem = document.getElementById('table');
// To keep this simple we assume there is only one button
let button = tableElem.getElementsByClassName('plusRow')[0];

button.addEventListener('click', event => {
    const name = event.currentTarget.getAttribute("table-data");
    tableData.addData(name, 0, 1);
    displayTable();
})

This version will only ever run when the first child of the table with a class of "plusRow" is clicked. Please note that this is just an example because if there is no element with such class an exception will be raised when we try to bind the event listener.


问:
Running multiple commands in parallel and exiting cleanly
In this example I have three commands running in parallel.

```<code>sleep 1 && echo 'one' &
sleep 2 && echo 'two'&
sleep 1 && echo 'three'&
sleep 2 && echo 'four' &
wait

echo "done"
</code>```

When I exit / quit the command with a keyboard shortcut the command still seems to be outputting.

```<code>➜  example: ✗ sh ./scripts.sh
three
one
two
four
done
➜  example: ✗ sh ./scripts.sh
^C%➜  example: ✗ one
three
two
four
</code>```

How can I cleanly exit?

答:
With @JithinScarla's help and this other stackoverflow post I made I put this together which seems to get the job done.

```<code>process_ids=( )

finish(){
    for i in "${process_ids[@]}"; do
        kill -9 $i > /dev/null 2> /dev/null || :
    done
}

append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax

{ sleep 1 && echo 'one'; } & append $!
{ sleep 5 && echo 'two'; } & append $!
{ sleep 1 && echo 'three'; } & append $!
{ sleep 5 && echo 'four'; } & append $!

echo "Background processes:"              # Demonstrate that our array was populated
printf ' - %s\n' "${process_ids[@]}"

trap finish EXIT

wait
</code>```

Or here even a bit cleaner:

```<code>function runParallel {
    process_ids=( )
    finish(){
        for i in "${process_ids[@]}"; do
            kill -9 $i > /dev/null 2> /dev/null || :
        done
    }
    append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax
    processes=( "$@" )
    for i in "${processes[@]}"; do
        { eval $i; } & append $!
    done
    trap finish EXIT
    wait
}

runParallel \
    "sleep 1 && echo 'one'" \
    "sleep 5 && echo 'two'" \
    "sleep 1 && echo 'three'" \
    "sleep 5 && echo 'four'"
</code>```

Body:
In this example I have three commands running in parallel.

sleep 1 && echo 'one' &
sleep 2 && echo 'two'&
sleep 1 && echo 'three'&
sleep 2 && echo 'four' &
wait

echo "done"

When I exit / quit the command with a keyboard shortcut the command still seems to be outputting.

➜  example: ✗ sh ./scripts.sh
three
one
two
four
done
➜  example: ✗ sh ./scripts.sh
^C%➜  example: ✗ one
three
two
four

How can I cleanly exit?

Body:
With @JithinScarla's help and this other stackoverflow post I made I put this together which seems to get the job done.

process_ids=( )

finish(){
    for i in "${process_ids[@]}"; do
        kill -9 $i > /dev/null 2> /dev/null || :
    done
}

append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax

{ sleep 1 && echo 'one'; } & append $!
{ sleep 5 && echo 'two'; } & append $!
{ sleep 1 && echo 'three'; } & append $!
{ sleep 5 && echo 'four'; } & append $!

echo "Background processes:"              # Demonstrate that our array was populated
printf ' - %s\n' "${process_ids[@]}"

trap finish EXIT

wait

Or here even a bit cleaner:

function runParallel {
    process_ids=( )
    finish(){
        for i in "${process_ids[@]}"; do
            kill -9 $i > /dev/null 2> /dev/null || :
        done
    }
    append() { process_ids+=( "$1" ); }       # POSIX-standard function declaration syntax
    processes=( "$@" )
    for i in "${processes[@]}"; do
        { eval $i; } & append $!
    done
    trap finish EXIT
    wait
}

runParallel \
    "sleep 1 && echo 'one'" \
    "sleep 5 && echo 'two'" \
    "sleep 1 && echo 'three'" \
    "sleep 5 && echo 'four'"


问:
Sitecore Web Api default context language
My target is if the request is

```<code>http://myapi.com/da-DK/api/products/all
</code>```

I would return the products from the DK language.

But if the request is

```<code>http://myapi.com/api/products/all
</code>```

meaning no language is requested, it would return products from a default language. In this case "en".

This is what I have in the webapiconfig.

```<code>config.Routes.MapHttpRoute(
                  name: "mypi",
                  routeTemplate: "{language}/api/{controller}/{action}/{id}",
                  defaults: new { id = RouteParameter.Optional, language = "en" }
              );
</code>```

The problem is if no language requested, it does not take english an default. Rather it takes the last requested language.
Can I somehow force sitecore to use default language if no language is requested?

答:
I know you solved this using a resolver but I think those are 2 different routes..meaning you can create another route:

```<code>config.Routes.MapHttpRoute(
              name: "mypinolang",
              routeTemplate: "api/{controller}/{action}/{id}",
              defaults: new { id = RouteParameter.Optional, language = "en" }
          );
</code>```

Then, you can have your API method to accept "language" as a parameter.  However, this answer may not work depending on your other API methods as it can get confusing.

Body:
My target is if the request is

http://myapi.com/da-DK/api/products/all

I would return the products from the DK language.

But if the request is

http://myapi.com/api/products/all

meaning no language is requested, it would return products from a default language. In this case "en".

This is what I have in the webapiconfig.

config.Routes.MapHttpRoute(
                  name: "mypi",
                  routeTemplate: "{language}/api/{controller}/{action}/{id}",
                  defaults: new { id = RouteParameter.Optional, language = "en" }
              );

The problem is if no language requested, it does not take english an default. Rather it takes the last requested language.
Can I somehow force sitecore to use default language if no language is requested?

Body:
I know you solved this using a resolver but I think those are 2 different routes..meaning you can create another route:

config.Routes.MapHttpRoute(
              name: "mypinolang",
              routeTemplate: "api/{controller}/{action}/{id}",
              defaults: new { id = RouteParameter.Optional, language = "en" }
          );

Then, you can have your API method to accept "language" as a parameter.  However, this answer may not work depending on your other API methods as it can get confusing.


问:
ISO 8601 extended duration format PnYnMnDTnHnMnS in R
Is there any way to parse ISO 8601 duration e.g. "P3Y6M4DT12H30M5S" and return something like:
"3 years, 6 months, 4 days, 12:30:05"

I had no luck with lubridate's durations or parsedate package.

答:
I am also not aware of any such package (may be it exists) to solve but you can use regex to parse it in your way, since the pattern will be fixed ("PnYnMnDTnHnMnS"), according to Wikipedia:

```<code>gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1 Years, \\2
Months, \\3 Days, \\4:\\5:\\6", "P3Y6M4DT12H30M5S")
</code>```

Output:

```<code>[1] "3 Years, 6 Months, 4 Days, 12:30:5"
</code>```

EDIT:

In case you are interested in only padding zeroes of seconds not anything else, I have added here two elements in the vector one with single digit of seconds, other with two digits of seconds(Assuming seconds will not go beyond 60) to validate the regex:

```<code>    vect <- c("P3Y6M4DT12H30M5S", "P3Y6M4DT12H30M15S")
    ifelse(grepl(".*M(\\d)S", vect), gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d)S", "\\1 Years, \\2 Months, \\3 Days, \\4:\\5:0\\6", vect), gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1 Years, \\2 Months, \\3 Days, \\4:\\5:\\6", vect))
</code>```

Output:

```<code>[1] "3 Years, 6 Months, 4 Days, 12:30:05"
[2] "3 Years, 6 Months, 4 Days, 12:30:15"
</code>```

In case you are interested in padding every element of single digit number:

```<code>topad <- gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1-\\2-\\3-\\4-\\5-\\6", vect)
library(stringr)
splitvect <- strsplit(topad,split="-")
unlist(lapply(splitvect, function(x)paste0(str_pad(x, 2, "0", side="left"), c("Years, ", "Months, ", "Days, ", ":", ":", ""), collapse= "")))
</code>```

Output:

```<code>[1] "03Years, 06Months, 04Days, 12:30:05"
[2] "03Years, 06Months, 04Days, 12:30:15"
</code>```

Body:
I am also not aware of any such package (may be it exists) to solve but you can use regex to parse it in your way, since the pattern will be fixed ("PnYnMnDTnHnMnS"), according to Wikipedia:

gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1 Years, \\2
Months, \\3 Days, \\4:\\5:\\6", "P3Y6M4DT12H30M5S")

Output:

[1] "3 Years, 6 Months, 4 Days, 12:30:5"

EDIT:

In case you are interested in only padding zeroes of seconds not anything else, I have added here two elements in the vector one with single digit of seconds, other with two digits of seconds(Assuming seconds will not go beyond 60) to validate the regex:

    vect <- c("P3Y6M4DT12H30M5S", "P3Y6M4DT12H30M15S")
    ifelse(grepl(".*M(\\d)S", vect), gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d)S", "\\1 Years, \\2 Months, \\3 Days, \\4:\\5:0\\6", vect), gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1 Years, \\2 Months, \\3 Days, \\4:\\5:\\6", vect))

Output:

[1] "3 Years, 6 Months, 4 Days, 12:30:05"
[2] "3 Years, 6 Months, 4 Days, 12:30:15"

In case you are interested in padding every element of single digit number:

topad <- gsub("P(\\d+)Y(\\d+)M(\\d+)DT(\\d+)H(\\d+)M(\\d+)S", "\\1-\\2-\\3-\\4-\\5-\\6", vect)
library(stringr)
splitvect <- strsplit(topad,split="-")
unlist(lapply(splitvect, function(x)paste0(str_pad(x, 2, "0", side="left"), c("Years, ", "Months, ", "Days, ", ":", ":", ""), collapse= "")))

Output:

[1] "03Years, 06Months, 04Days, 12:30:05"
[2] "03Years, 06Months, 04Days, 12:30:15"


问:
How do I create an RxJS Observable that resolves after .75 seconds?
I would like to create an Observable which resolves after .75 seconds. I tried doing so like this, but the Observable is resolving immediately:

```<code>import { Observable } from 'rxjs/Observable';
import { delay } from 'rxjs/operators/delay';
...
refresh(): Observable<any> {
  // Return an observable that resolves after .75 seconds
  return Observable.create().pipe( delay(750) );
}
</code>```

I am using rxjs version 5.5.2 and typescript version 2.4.2

答:
If you want the timer to be the source then you could do the following:

console.log('start');
Rx.Observable.timer(750)
  .subscribe(
    x => console.log('next:', x),
    null,
    () => console.log('complete')
  );```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script></code>```

Here are the docs: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-timer

You have to actually pass something into the create method btw. If you don't I think it throws the following error: Cannot read property 'subscribe' of undefined

If you want to defer returning some observable then you could do something like this:

console.log('start');
Rx.Observable.create(o => { o.next('test'); o.complete(); })
  .delay(750)
  .subscribe(
    x => console.log('next:', x),
    null,
    () => console.log('complete')
  );```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script></code>```

Sorry I used old style syntax since I couldn't get the import for the operator to work in the editor.

Body:
I would like to create an Observable which resolves after .75 seconds. I tried doing so like this, but the Observable is resolving immediately:

import { Observable } from 'rxjs/Observable';
import { delay } from 'rxjs/operators/delay';
...
refresh(): Observable<any> {
  // Return an observable that resolves after .75 seconds
  return Observable.create().pipe( delay(750) );
}

I am using rxjs version 5.5.2 and typescript version 2.4.2

Body:
If you want the timer to be the source then you could do the following:

console.log('start');
Rx.Observable.timer(750)
  .subscribe(
    x => console.log('next:', x),
    null,
    () => console.log('complete')
  );

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

Here are the docs: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-timer

You have to actually pass something into the create method btw. If you don't I think it throws the following error: Cannot read property 'subscribe' of undefined

If you want to defer returning some observable then you could do something like this:

console.log('start');
Rx.Observable.create(o => { o.next('test'); o.complete(); })
  .delay(750)
  .subscribe(
    x => console.log('next:', x),
    null,
    () => console.log('complete')
  );

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

Sorry I used old style syntax since I couldn't get the import for the operator to work in the editor.


问:
Accessing an email attachment as an object
OK so I have a script that goes through my outlook inbox looking for a particular header string. This works great for emails directly in my inbox. Now I'm trying to expand this detection to emails that contain other emails as attachments. I've spent significant time researching this and I can't seem to find the proper way to access the email attachment directly. What I've ended up doing is saving the attachment to disc and then reading it back in using CreateItemFromTemplate. I find this to be a cludge solution and I'm hoping someone here can help me find a more elegant way to do this where I can bypass the saveas as CreateItemFromTemplate and directly create an item object from the attachment. Here is proof of concept script I've put together for this:</p>

```<code>Const olFolderInbox = 6
Const olMail = 43
Const olEmbeddeditem = 5
Const PropName = "http://schemas.microsoft.com/mapi/proptag/0x007D001E"

Set app = CreateObject("Outlook.Application")
set objNamespace = app.GetNamespace("MAPI")
set objInboxItems = objNameSpace.GetDefaultFolder(olFolderInbox).items
wscript.echo "Have your inbox open checking for fish tests or emails as attachments"
for each objItem in objInboxItems
    if objItem.Class = olMail then
        with objItem
            strHeader = .PropertyAccessor.GetProperty(PropName)
            iLoc1 = instr(1,strHeader,"X-Testing",1)
            if iLoc1 > 0 then
                wscript.echo "mytest. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
            end if
            iLoc1 = instr(1,strHeader,"X-PHISHTEST",1)
            if iLoc1 > 0 then
                wscript.echo "Go Fish. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
            end if
            if .attachments.count > 0 then
                set objAttachment = .attachments.item(1)
                if objAttachment.type = olEmbeddeditem then
                    wscript.echo "Has Attachment. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
                    wscript.echo " - Filename: " & objAttachment.Filename
                    objAttachment.SaveAsFile ("c:\temp\TempEmail.msg")
                    set objExtMsg = app.CreateItemFromTemplate("c:\temp\TempEmail.msg")
                    strExtHeader = objExtMsg.PropertyAccessor.GetProperty(PropName)
                    iLoc1 = instr(1,strExtHeader,"X-Testing",1)
                    if iLoc1 > 0 then wscript.echo " ++ This is a plain test message"
                end if
            end if
        end with
    end if
next
wscript.echo "That's all folks"    `
</code>```

答:
That is the best you can do in OOM alone - save the attachment as an MSG file and then reopen it. OpenSharedItem is a better way to open an MSG file than CreateItemFromTemplate.

On the Extended MAPI level (C++ or Delphi), you can open the PR_ATTACH_DATA_OBJ property as IMessage using IAttach::OpenProperty. If Extended MAPI is not an option, you can use Redemption (I am its author - any language) - both Safe*Item and RDO families of objects expose EmbeddedMsg property on the attachment object that return the attachment message.

Body:
OK so I have a script that goes through my outlook inbox looking for a particular header string. This works great for emails directly in my inbox. Now I'm trying to expand this detection to emails that contain other emails as attachments. I've spent significant time researching this and I can't seem to find the proper way to access the email attachment directly. What I've ended up doing is saving the attachment to disc and then reading it back in using CreateItemFromTemplate. I find this to be a cludge solution and I'm hoping someone here can help me find a more elegant way to do this where I can bypass the saveas as CreateItemFromTemplate and directly create an item object from the attachment. Here is proof of concept script I've put together for this:

Const olFolderInbox = 6
Const olMail = 43
Const olEmbeddeditem = 5
Const PropName = "http://schemas.microsoft.com/mapi/proptag/0x007D001E"

Set app = CreateObject("Outlook.Application")
set objNamespace = app.GetNamespace("MAPI")
set objInboxItems = objNameSpace.GetDefaultFolder(olFolderInbox).items
wscript.echo "Have your inbox open checking for fish tests or emails as attachments"
for each objItem in objInboxItems
    if objItem.Class = olMail then
        with objItem
            strHeader = .PropertyAccessor.GetProperty(PropName)
            iLoc1 = instr(1,strHeader,"X-Testing",1)
            if iLoc1 > 0 then
                wscript.echo "mytest. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
            end if
            iLoc1 = instr(1,strHeader,"X-PHISHTEST",1)
            if iLoc1 > 0 then
                wscript.echo "Go Fish. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
            end if
            if .attachments.count > 0 then
                set objAttachment = .attachments.item(1)
                if objAttachment.type = olEmbeddeditem then
                    wscript.echo "Has Attachment. From: " & .Sender & " at: " & .ReceivedTime & " subjet: " & .Subject
                    wscript.echo " - Filename: " & objAttachment.Filename
                    objAttachment.SaveAsFile ("c:\temp\TempEmail.msg")
                    set objExtMsg = app.CreateItemFromTemplate("c:\temp\TempEmail.msg")
                    strExtHeader = objExtMsg.PropertyAccessor.GetProperty(PropName)
                    iLoc1 = instr(1,strExtHeader,"X-Testing",1)
                    if iLoc1 > 0 then wscript.echo " ++ This is a plain test message"
                end if
            end if
        end with
    end if
next
wscript.echo "That's all folks"    `

ContentLicense: CC BY-SA 4.0


问:
Is there a way how to use [switch] parameter in Azure Runbook
I have a small script I'm migrating to Azure Automation account as Azure Runbook.
Originally, the script was using some switch parameters for example -WhatIf.

```<code>#Requires -Version 3.0
[cmdletbinding()]
param(
 #//Other parameters
[switch]$WhatIf
 #//Other parameters
)
if ($WhatIf.IsPresent) {
 #////Do something
}
</code>```

But when I try to test it in the test pane I'm not able to pass any value into it.

I tried 1,0, $True, $true, True, False but nothing seems working. I know I can change the type of the parameter, but I was wondering there might be a better way. Is there?

答:
Whilst you can use Switch parameters in Azure Automation Runbooks, the best practice advice is to use [bool] instead.  You can default it to false, and even check if it's been passed in (if you want/need to for any reason).  This would make your function look as follows:</p>

```<code>#Requires -Version 3.0
[CmdletBinding()]
param (
    [Parameter (Mandatory = $false)]
    [bool]$WhatIf
)

# Check if user supplied $WhatIf parameter
if ($PSBoundParameters.ContainsKey('WhatIf')) {
    # User specified -WhatIf
} else {
    # User did not specify -WhatIf
}

# Simple parameter check - can't differentiate between $false supplied by user and parameter not supplied
if ($WhatIf) {
    # User specified -WhatIf
} else {
    # User did not specify -WhatIf
}
</code>```

Body:
I have a small script I'm migrating to Azure Automation account as Azure Runbook.
Originally, the script was using some switch parameters for example -WhatIf.

#Requires -Version 3.0
[cmdletbinding()]
param(
 #//Other parameters
[switch]$WhatIf
 #//Other parameters
)
if ($WhatIf.IsPresent) {
 #////Do something
}

But when I try to test it in the test pane I'm not able to pass any value into it.

I tried 1,0, $True, $true, True, False but nothing seems working. I know I can change the type of the parameter, but I was wondering there might be a better way. Is there?

Body:
Whilst you can use Switch parameters in Azure Automation Runbooks, the best practice advice is to use [bool] instead.  You can default it to false, and even check if it's been passed in (if you want/need to for any reason).  This would make your function look as follows:

#Requires -Version 3.0
[CmdletBinding()]
param (
    [Parameter (Mandatory = $false)]
    [bool]$WhatIf
)

# Check if user supplied $WhatIf parameter
if ($PSBoundParameters.ContainsKey('WhatIf')) {
    # User specified -WhatIf
} else {
    # User did not specify -WhatIf
}

# Simple parameter check - can't differentiate between $false supplied by user and parameter not supplied
if ($WhatIf) {
    # User specified -WhatIf
} else {
    # User did not specify -WhatIf
}


问:
Compressing a JPG image to a given size in KB?
I have a byte array returned by the camera in input.

I need to scale down my image to make its size equal to 500KB. I am trying to achieve this using a Bitmap, but I cannot find how to get the proper compression value.

```<code>public static byte[] compressCapture(byte[] capture) {

    // How to get the right compression value ?
    int compression = 50;

    Bitmap bitmap  = BitmapFactory.decodeByteArray(capture, 0, capture.length);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, compression, outputStream);
    return outputStream.toByteArray();
}
</code>```

The problem is that the compression is not proportional to the image size, meaning that compression equals to 50 will not divide the image size by 2.

Is there a way to get a fixed image size in output that does not depend on the focus, or the smartphone model ?

EDIT :

I do not want to use a File (I work with confidential data).

答:
The problem you face is that the compression depends upon the nature of the image. My guess is that there is academic research that looks at the image and selects the parameters to reach a given size.

In JPEG you have several settings to reduce size:

The inclusion or exclusion of COM and APPn markers.

Whether optimized or off-the-shelf Huffman tables are used.

The selection of quantization tables.

Subsampling of Cb and Cr components.

Progressive or Sequential encoding (if the former, you have an plethora of scan settings at your disposal).

Still, it's mostly trial and error.

Body:
I have a byte array returned by the camera in input.

I need to scale down my image to make its size equal to 500KB. I am trying to achieve this using a Bitmap, but I cannot find how to get the proper compression value.

public static byte[] compressCapture(byte[] capture) {

    // How to get the right compression value ?
    int compression = 50;

    Bitmap bitmap  = BitmapFactory.decodeByteArray(capture, 0, capture.length);
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, compression, outputStream);
    return outputStream.toByteArray();
}

The problem is that the compression is not proportional to the image size, meaning that compression equals to 50 will not divide the image size by 2.

Is there a way to get a fixed image size in output that does not depend on the focus, or the smartphone model ?

EDIT :

I do not want to use a File (I work with confidential data).


问:
PHP totalling column and simplifying Sessions
I'm trying to total a column in a table of prices and it's not working out for me. I've looked at a ton of solutions such as array_sum() but it's not displaying anything for me. This is a cart page where I'm posting items to a session and then displaying in a for loop. I'm not sure if my sessions are overly complicated or what. Here is my session and post code:

```<code>session_start();

if( $_SERVER['REQUEST_METHOD'] == 'POST') {
    $_SESSION['item'][] = array($_POST['item'], $_POST['price']);
}

?>
</code>```

And here is my for loop section of code:

```<code>for($i=0; $i < count($_SESSION['item']); $i++){
    $prices = $_SESSION['item'][$i][1];
         $sum = 0;
         $sum += $_SESSION['item'][$i][1];
         print $sum;
?>

<tr>
    <td class="left"> <?php print_r($_SESSION['item'][$i][0]) ?></td>
    <td class="center"><?php echo "$ " . $_SESSION['item'][$i][1] ?></td>
</tr>

<?php
}
?>

<tr>
    <td class="center">Total:</td>
    <td></td>
</tr>

<?php
}
?>

</table><br>
</code>```

Any help would be greatly appreciated!

答:
Replace your current forloop with the following:

You were assigning $sum=0; inside loop so every time loop executed, your $sum variable would be assigned to zero and hence you would lose its value.

Sidenote: You should consider printing sum outside of loop.

```<code>$sum = 0;
for($i=0; $i < count($_SESSION['item']); $i++){
    $prices = $_SESSION['item'][$i][1];
    $sum += $_SESSION['item'][$i][1];
    print $sum;
?>
</code>```

Body:
I'm trying to total a column in a table of prices and it's not working out for me. I've looked at a ton of solutions such as array_sum() but it's not displaying anything for me. This is a cart page where I'm posting items to a session and then displaying in a for loop. I'm not sure if my sessions are overly complicated or what. Here is my session and post code:

session_start();

if( $_SERVER['REQUEST_METHOD'] == 'POST') {
    $_SESSION['item'][] = array($_POST['item'], $_POST['price']);
}

?>

And here is my for loop section of code:

for($i=0; $i < count($_SESSION['item']); $i++){
    $prices = $_SESSION['item'][$i][1];
         $sum = 0;
         $sum += $_SESSION['item'][$i][1];
         print $sum;
?>

     <?php print_r($_SESSION['item'][$i][0]) ?>
    <?php echo "$ " . $_SESSION['item'][$i][1] ?>

<?php
}
?>

    Total:

<?php
}
?>

Any help would be greatly appreciated!

Body:
Replace your current forloop with the following:

You were assigning $sum=0; inside loop so every time loop executed, your $sum variable would be assigned to zero and hence you would lose its value.

Sidenote: You should consider printing sum outside of loop.

$sum = 0;
for($i=0; $i < count($_SESSION['item']); $i++){
    $prices = $_SESSION['item'][$i][1];
    $sum += $_SESSION['item'][$i][1];
    print $sum;
?>


问:
jQuery passing parameters into .ajax()
I'm having issues passing parameters/variables into the ajax() function.

The function below accepts two parameters. One is 'element', the success option of .ajax() uses, that works fine so no need to focus on that. The 'tx' is either a single value like 'menu' or a couple of values separated by a colon like this: "menu:categories:brands"

If there is only one value in 'tx' then only one AJAX request needs to be sent and that works fine. If there is more than one value in 'tx' the function split's it using ":" is the delimiter and then passes offset[0] as the value of 'tx' into the AJAX request and then store's the rest of the values in 'x'.

What I'm having issues with is running this function recursively once the AJAX request is complete for the first value. The var 'more' stores a bool value if there is more values left to process or not. However, when I write in an if argument using 'more == true' into the success or complete option of .ajax() it doesn't reflect the value stored in that variables, it always returns false.

Before some one answers, with "You should structure the function that calls this function to only pass a single value into that parameter," lets suppose that this is an impossible venture that is outside the realm of my control.

I have no idea why this happening. I know it's probably something very simple that I'm overlooking but I've been up for about 16 hours now and this issue has plagued me for at least half that time.

Any help here is appreciated. Here is the function:

```<code>function getContent(element, tx) {
    e = element
    modAmount = tx.split(':')
    if (modAmount.length > 1) {
        x = ''
        tx = modAmount[0]
        for (i=1;i<modAmount.length;i++) {
            x = x + modAmount[i]
            if (i != (modAmount.length)-1){
                x = x+":"
            }
        }
        more = true
    }
    else {
        more = false
        tx = modAmount[0]
    }
    $.ajax({
        type: "POST",
        url: "getModule.php",
        data: "modName="+tx+"&DB=<?php echo DB ?>",
        success: function(data){
            if ($( element ).find('p').text() == "No Content"){
                $( element ).find('p').remove();
                $( element ).html("<div onclick='destroy(this)' id='destroy' class='ui-corner-all destroy' title='Remove Module'>"+data+"</div>")
            }
            else {
                $( element ).append("<div onclick='destroy(this)' id='destroy' class='ui-corner-all destroy' title='Remove Module'>"+data+"</div>");
            }
        },
        complete: function() {
            if (more == true) {alert(x)} // always returns false
        }
    });

}
</code>```

答:
Because "more" isn't scoped within your callbacks.

I recommend using the context property you can send to the ajax call to set the "this" variable in success/complete callbacks:

http://api.jquery.com/jQuery.ajax/

Title: jQuery passing parameters into .ajax()

Body:
I'm having issues passing parameters/variables into the ajax() function.

The function below accepts two parameters. One is 'element', the success option of .ajax() uses, that works fine so no need to focus on that. The 'tx' is either a single value like 'menu' or a couple of values separated by a colon like this: "menu:categories:brands"

If there is only one value in 'tx' then only one AJAX request needs to be sent and that works fine. If there is more than one value in 'tx' the function split's it using ":" is the delimiter and then passes offset[0] as the value of 'tx' into the AJAX request and then store's the rest of the values in 'x'.

What I'm having issues with is running this function recursively once the AJAX request is complete for the first value. The var 'more' stores a bool value if there is more values left to process or not. However, when I write in an if argument using 'more == true' into the success or complete option of .ajax() it doesn't reflect the value stored in that variables, it always returns false.

Before some one answers, with "You should structure the function that calls this function to only pass a single value into that parameter," lets suppose that this is an impossible venture that is outside the realm of my control.

I have no idea why this happening. I know it's probably something very simple that I'm overlooking but I've been up for about 16 hours now and this issue has plagued me for at least half that time.

Any help here is appreciated. Here is the function:

function getContent(element, tx) {
    e = element
    modAmount = tx.split(':')
    if (modAmount.length > 1) {
        x = ''
        tx = modAmount[0]
        for (i=1;i<modAmount.length;i++) {
            x = x + modAmount[i]
            if (i != (modAmount.length)-1){
                x = x+":"
            }
        }
        more = true
    }
    else {
        more = false
        tx = modAmount[0]
    }
    $.ajax({
        type: "POST",
        url: "getModule.php",
        data: "modName="+tx+"&DB=<?php echo DB ?>",
        success: function(data){
            if ($( element ).find('p').text() == "No Content"){
                $( element ).find('p').remove();
                $( element ).html("
"+data+"
")
            }
            else {
                $( element ).append("
"+data+"
");
            }
        },
        complete: function() {
            if (more == true) {alert(x)} // always returns false
        }
    });

}


问:
c# Switch case not working
I'm trying to check a value by using a switch:

private void btnInput1Rste_Click(object sender, EventArgs e)
{
    switch (sender == btnInput1Rste)
    {
        case "1": currentButtonPressedRste = 1;
            break;
    }
}
```

It gives the error as follows:

can't convert type 'string' to 'bool'

However, when i try to convert it to a boolean it says:

a constant value is expected.

How do I fix it?

When it works it's supposed to check 3 values. (not with just this switch)

答: Here's the issue. Whatever type is in the parentheses of the switch statement must match the types of the cases. Here, you have a boolean value in the parentheses. Your case is checking for a string type. Bools and strings cannot be implicitly converted to one another, hence the error.</p>

Title: c# Switch case not working

Body:
I'm trying to check a value by using a switch:

private void btnInput1Rste_Click(object sender, EventArgs e)
{
    switch (sender == btnInput1Rste)
    {
        case "1": currentButtonPressedRste = 1;
            break;
    }
}

It gives the error as follows:

can't convert type 'string' to 'bool'

However, when i try to convert it to a boolean it says:

a constant value is expected.

How do I fix it?

When it works it's supposed to check 3 values. (not with just this switch)