问:
C# Memory Concerns
I work with cellular automata. My repo for my work is here. The basic structure is

1) A grid of
2) cells, which may have
3) agents.

The agents act according to a set of rules, and typically one designates "states" for the agents (agents of different states have different rules). One (relatively) well-known CA is the game of life.

I'm trying to expand things a bit more and incorporate other types of "properties" in my CAs, mainly to simulate various phenomena (imagine an animal agent that consumes a plant agent, with the plant's "biomass" or what have you decreasing).

To do this I'm incorporating a normal dictionary, with strings as keys and a struct called CAProperty as the value. The struct is as follows:

```<code>public struct CAProperty
{
    public readonly string name;
    public readonly dynamic value;
    //public readonly Type type;
    public CAProperty(string name, dynamic value)
    {
        this.name = name;
        this.value = value;
    }
}
</code>```

(note: previously I had the "type" variable to enable accurate typing at runtime...but in attempts to solve the issue in this post I removed it. Fact is, it'll need to be added back in)

This is well and good. However, I'm trying to do some work with large grid sizes. 100x100. 1000x1000. 5000x5000, or 25 million cells (and agents). That would be 25 million dictionaries.

See the image: a memory snapshot from Visual Studio for a 4000x4000 grid, or 16 million agents (I tried 5000x5000, but Visual Studio wouldn't let me take a snapshot).

On the right, one can clearly see that the debugger is reading 8 GB memory usage (and I tried this in a release version to see 6875 MB usage). However, when I count up everything in the third column of the snapshot, I arrive at less than 4 GB.

Why is there such a dramatic discrepancy between the total memory usage and the size of objects stored in memory?

Additionally: how might I optimize memory usage (mainly the dictionaries - is there another collection with similar behavior but lower memory usage)?

Edit: For each of the three "components" (Grid, Cell, Agent) I have a class. They all inherit from an original CAEntity class. All are shown below.

```<code>    public abstract class CAEntity
    {
        public CAEntityType Type { get; }
        public Dictionary<string, dynamic> Properties { get; private set; }

        public CAEntity(CAEntityType type)
        {
            this.Type = type;
        }

        public CAEntity(CAEntityType type, Dictionary<string, dynamic> properties)
        {
            this.Type = type;
            if(properties != null)
            {
                this.Properties = new Dictionary<string, dynamic>(properties);
            }
        }
    }

    public class CAGraph:CAEntity
    {
        public ValueTuple<ushort, ushort, ushort> Dimensions { get; }
        public CAGraphCell[,,] Cells { get;}
        List<ValueTuple<ushort, ushort, ushort>> AgentCells { get; set; }
        List<ValueTuple<ushort, ushort, ushort>> Updates { get; set; }
        public CA Parent { get; private set; }
        public GridShape Shape { get; }
        //List<double> times = new List<double>();
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraph (CA parent, ValueTuple<ushort, ushort, ushort> size, GridShape shape):base(CAEntityType.Graph)
        {
            this.Parent = parent;
            this.Shape = shape;
            AgentCells = new List<ValueTuple<ushort, ushort, ushort>>();
            Updates = new List<ValueTuple<ushort, ushort, ushort>>();
            Dimensions = new ValueTuple<ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
            Cells = new CAGraphCell[size.Item1, size.Item2, size.Item3];
            for (ushort i = 0; i < Cells.GetLength(0); i++)
            {
                for (ushort j = 0; j < Cells.GetLength(1); j++)
                {
                    for (ushort k = 0; k < Cells.GetLength(2); k++)
                    {
                        Cells[i, j, k] = new CAGraphCell(this, new ValueTuple<ushort, ushort, ushort>(i, j, k));
                    }
                }
            }
        }

        public CAGraph(CA parent, ValueTuple<ushort, ushort, ushort> size, GridShape shape, List<ValueTuple<ushort, ushort, ushort>> agents, CAGraphCell[,,] cells, Dictionary<string, dynamic> properties) : base(CAEntityType.Graph, properties)
        {
            Parent = parent;
            Shape = shape;
            AgentCells = agents.ConvertAll(x => new ValueTuple<ushort, ushort, ushort>(x.Item1, x.Item2, x.Item3));
            Updates = new List<ValueTuple<ushort, ushort, ushort>>();
            Dimensions = new ValueTuple<ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
            Cells = new CAGraphCell[size.Item1, size.Item2, size.Item3];
            for (ushort i = 0; i < size.Item1; i++)
            {
                for (ushort j = 0; j < size.Item2; j++)
                {
                    for (ushort k = 0; k < size.Item3; k++)
                    {
                        //if(i == 500 && j == 500)
                        //{
                        //    Console.WriteLine();
                        //}
                        Cells[i, j, k] = cells[i, j, k].Copy(this);
                    }
                }
            }
        }
    }

    public class CAGraphCell:CAEntity
    {
        public CAGraph Parent { get; set; }
        public CAGraphCellAgent Agent { get; private set; }
        public ValueTuple<ushort, ushort, ushort> Position { get; private set; }
        //private Tuple<ushort, ushort, ushort>[][] Neighbors { get; set; }
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraphCell(CAGraph parent, ValueTuple<ushort, ushort, ushort> position):base(CAEntityType.Cell)
        {
            this.Parent = parent;
            this.Position = position;
            //this.Neighbors = new Tuple<ushort, ushort, ushort>[Enum.GetNames(typeof(CANeighborhoodType)).Count()][];
        }

        public CAGraphCell(CAGraph parent, ValueTuple<ushort, ushort, ushort> position, Dictionary<string, dynamic> properties, CAGraphCellAgent agent) :base(CAEntityType.Cell, properties)
        {
            this.Parent = parent;
            this.Position = position;
            if(agent != null)
            {
                this.Agent = agent.Copy(this);
            }
        }
    }

    public class CAGraphCellAgent:CAEntity
    {
        // have to change...this has to be a property? Or no, it's a CAEntity which has a list of CAProperties.
        //public int State { get; set; }
        public CAGraphCell Parent { get; set; }
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraphCellAgent(CAGraphCell parent, ushort state):base(CAEntityType.Agent)
        {
            this.Parent = parent;
            AddProperty(("state", state));
        }

        public CAGraphCellAgent(CAGraphCell parent, Dictionary<string, dynamic> properties) :base(CAEntityType.Agent, properties)
        {
            this.Parent = parent;
        }
    }
</code>```

答:
It sounds like your problem is that your representation of your agents (using dictionaries) consumes too much memory.  If so, the solution is to find a more compact representation.

Since you're working in an object-oriented language, the typical solution would be to define an Agent class, possibly with subclasses for different types of agents, and use instance variables to store the state of each agent.  Then your CA grid will be an array of Agent instances (or possibly nulls for vacant cells).  This will be a lot more compact than using dictionaries with string keys.

Also, I would recommend not storing the position of the agent on the grid as part of the agent's state, but passing it as a parameter to any methods that need it.  Not only does this save a bit of memory just by itself, but it also allows you to place references to the same Agent instance at multiple cells on the grid to represent multiple identical agents.  Depending on how often such identical agents occur in your CA, this may save a huge amount of memory.

Note that, if you modify the state of such a reused agent instance, the modification will obviously affect all agents on the grid represented by that instance.  For that reason, it may be a good idea to make your Agent objects immutable and just create a new one whenever the agent's state changes.

You might also want to consider maintaining a cache (e.g. a set) of Agent instances already on the grid so that you can easily check if a new agent might be identical with an existing one.  Whether this will actually do any good depends on your specific CA model — with some CA you might be able to handle de-duplication sufficiently well even without such a cache (it's perfectly OK to have some duplicate Agent objects), while for others there might simply not be enough identical agents to make it worthwhile.  Also, if you do try this, note that you'll need to either design the cache to use weak references (which can be tricky to get right) or periodically purge and rebuild it to avoid old Agent objects lingering in the cache even after they've been removed from the grid.

Addendum based on your comment below, which I'll quote here:

Imagine an environment where the temperature varies seasonally (so a property on the graph). There are land and water cells (so properties on cells), and in low enough temperatures the water cells become frozen so animal agents can use them to cross over between land locations. Imagine those animal agents hunt other animal agents to eat them (so properties on the agents). Imagine the animal agents that get eaten eat trees (so other agents with properties), and tend to eat young saplings (limiting tree growth), thereby limiting their own growth (and that of the carnivore agents).

OK, so let's sketch out the classes you'd need.  (Please excuse any syntax errors; I'm not really a C# programmer and I haven't actually tested this code.  Just think of it as C#-like pseudocode or something.)

First of all, you will obviously need a bunch of agents.  Let's define an abstract superclass for them:

```<code>public abstract class Agent {
    public abstract void Act(Grid grid, int x, int y, float time);
}
</code>```

Our CA simulation (which, for simplicity, I'm going to assume to be stochastic, i.e. one where the agents act one at a time in a random order, like in the Gillespie algorithm) is basically going to involve repeatedly picking a random cell (x, y) on the grid, checking if that cell contains an agent, and if so, calling Act() on that agent.  (We'll also need to update any time-dependent global state while we're doing that, but let's leave that for later.)

The Act() methods for the agents will receive a reference to the grid object, and can call its methods to make changes to the state of nearby cells (or even get a reference to the agents in those cells and call their methods directly).  This could involve e.g. removing another agent from the grid (because it just got eaten), adding a new agent (reproduction), changing the acting agent's location (movement) or even removing that agent from the grid (e.g. because it starved or died of old age).  For illustration, let's sketch a few agent classes:

```<code>public class Sapling : Agent {
    private static readonly double MATURATION_TIME = 10;  // arbitrary time delay

    private double birthTime;  // could make this a float to save memory
    public Sapling(double time) => birthTime = time;

    public override void Act(Grid grid, int x, int y, double time) {
        // if the sapling is old enough, it replaces itself with a tree
        if (time >= birthTime + MATURATION_TIME) {
            grid.SetAgentAt(x, y, Tree.INSTANCE);
        }
    }
}

public class Tree : Agent {
    public static readonly Tree INSTANCE = new Tree();

    public override void Act(Grid grid, int x, int y, double time) {
        // trees create saplings in nearby land cells
        (int x2, int y2) = grid.RandomNeighborOf(x, y);
        if (grid.GetAgentAt(x2, y2) == null && grid.CellTypeAt(x2, y2) == CellType.Land) {
            grid.SetAgentAt(x2, y2, new Sapling(time));
        }
    }
}
</code>```

For the sake of brevity, I'll leave the implementation of the animal agents as an exercise.  Also, the Tree and Sapling implementations above are kind of crude and could be improved in various ways, but they should at least illustrate the concept.

One thing worth noting is that, to minimize memory usage, the agent classes above have as little internal state as possible.  In particular, the agents don't store their own location on the grid, but will receive it as arguments to the act() method.  Since omitting the location in fact made my Tree class completely stateless, I went ahead and used the same global Tree instance for all trees on the grid!  While this won't always be possible, when it is, it can save a lot of memory.

Now, what about the grid?  A basic implementation (ignoring the different cell types for a moment) would look something like this:

```<code>public class Grid {
    private readonly int width, height;
    private readonly Agent?[,] agents;

    public Grid(int w, int h) {
        width = w;
        height = h;
        agents = new Agent?[w, h];
    }

    // TODO: handle grid edges
    public Agent? GetAgentAt(int x, int y) => agents[x, y];
    public void SetAgentAt(int x, int y, Agent? agent) => agents[x, y] = agent;
}
</code>```

Now, what about the cell types?  You have a couple of ways to handle those.

One way would be to make the grid store an array of Cell objects instead of agents, and have each cell store its state and (possibly) an agent.  But for optimizing memory use it's probably better to just have a separate 2D array storing the cell types, something like this:

```<code>public enum CellType : byte { Land, Water, Ice }

public class Grid {
    private readonly Random rng = new Random();
    private readonly int width, height;
    private readonly Agent?[,] agents;
    private readonly CellType[,] cells;  // TODO: init in constructor?

    private float temperature = 20;  // global temperature in Celsius

    // ...

    public CellType CellTypeAt(int x, int y) {
        CellType type = cells[x,y];
        if (type == CellType.Water && temperature < 0) return CellType.Ice;
        else return type;
    }
}
</code>```

Note how the CellType enum is byte-based, which should keep the array storing them a bit more compact than if they were int-based.

Now, let's finally look at the main CA simulation loop.  At its most basic, it could look like this:

```<code>Grid grid = new Grid(width, height);
grid.SetAgentAt(width / 2, height / 2, Tree.INSTANCE);

// average simulation time per loop iteration, assuming that each
// actor on the grid acts once per unit time step on average
double dt = 1 / (width * height);

for (double t = 0; t < maxTime; t += dt) {
    (int x, int y) = grid.GetRandomLocation();
    Agent? agent = grid.GetAgentAt(x, y);
    if (agent != null) agent.Act(grid, x, y, t);
    // TODO: update temperature here?
}
</code>```

(Technically, to correctly implement the Gillespie algorithm, the simulation time increment between iterations should be an exponentially distributed random number with mean dt, not a constant increment.  However, since only the actor on one of the width * height cells is chosen in each iteration, the number of iterations between actions by the same actor is geometrically distributed with mean width * height, and multiplying this by dt = 1 / (width * height) gives an excellent approximation for an exponential distribution with mean 1.  Which is a long-winded way of saying that in practice using a constant time step is perfectly fine.)

Since this is getting long enough, I'll let you continue from here.  I'll just note that there are plenty of ways to further expand and/or optimize the algorithm I've sketched above.

For example, you could speed up the simulation by maintaining a list of all grid locations that contain a live actor and randomly sampling actors from that list (but then you'd also need to scale the time step by the inverse of the length of the list).  Also, you may decide that you want some actors to get more frequent chances to act than others; while the simple way to do that is just to use rejection sampling (i.e. have the actor only do something if rng.Sample() < prob for some prob between 0 and 1), a more efficient way would be to maintain multiple lists of locations depending on the type of the actor there.

Title: C# Memory Concerns

Body:
I work with cellular automata. My repo for my work is here. The basic structure is

1) A grid of
2) cells, which may have
3) agents.

The agents act according to a set of rules, and typically one designates "states" for the agents (agents of different states have different rules). One (relatively) well-known CA is the game of life.

I'm trying to expand things a bit more and incorporate other types of "properties" in my CAs, mainly to simulate various phenomena (imagine an animal agent that consumes a plant agent, with the plant's "biomass" or what have you decreasing).

To do this I'm incorporating a normal dictionary, with strings as keys and a struct called CAProperty as the value. The struct is as follows:

public struct CAProperty
{
    public readonly string name;
    public readonly dynamic value;
    //public readonly Type type;
    public CAProperty(string name, dynamic value)
    {
        this.name = name;
        this.value = value;
    }
}

(note: previously I had the "type" variable to enable accurate typing at runtime...but in attempts to solve the issue in this post I removed it. Fact is, it'll need to be added back in)

This is well and good. However, I'm trying to do some work with large grid sizes. 100x100. 1000x1000. 5000x5000, or 25 million cells (and agents). That would be 25 million dictionaries.

See the image: a memory snapshot from Visual Studio for a 4000x4000 grid, or 16 million agents (I tried 5000x5000, but Visual Studio wouldn't let me take a snapshot).

On the right, one can clearly see that the debugger is reading 8 GB memory usage (and I tried this in a release version to see 6875 MB usage). However, when I count up everything in the third column of the snapshot, I arrive at less than 4 GB.

Why is there such a dramatic discrepancy between the total memory usage and the size of objects stored in memory?

Additionally: how might I optimize memory usage (mainly the dictionaries - is there another collection with similar behavior but lower memory usage)?

Edit: For each of the three "components" (Grid, Cell, Agent) I have a class. They all inherit from an original CAEntity class. All are shown below.

    public abstract class CAEntity
    {
        public CAEntityType Type { get; }
        public Dictionary<string, dynamic> Properties { get; private set; }

        public CAEntity(CAEntityType type)
        {
            this.Type = type;
        }

        public CAEntity(CAEntityType type, Dictionary<string, dynamic> properties)
        {
            this.Type = type;
            if(properties != null)
            {
                this.Properties = new Dictionary<string, dynamic>(properties);
            }
        }
    }

    public class CAGraph:CAEntity
    {
        public ValueTuple<ushort, ushort, ushort> Dimensions { get; }
        public CAGraphCell[,,] Cells { get;}
        List<ValueTuple<ushort, ushort, ushort>> AgentCells { get; set; }
        List<ValueTuple<ushort, ushort, ushort>> Updates { get; set; }
        public CA Parent { get; private set; }
        public GridShape Shape { get; }
        //List<double> times = new List<double>();
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraph (CA parent, ValueTuple<ushort, ushort, ushort> size, GridShape shape):base(CAEntityType.Graph)
        {
            this.Parent = parent;
            this.Shape = shape;
            AgentCells = new List<ValueTuple<ushort, ushort, ushort>>();
            Updates = new List<ValueTuple<ushort, ushort, ushort>>();
            Dimensions = new ValueTuple<ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
            Cells = new CAGraphCell[size.Item1, size.Item2, size.Item3];
            for (ushort i = 0; i < Cells.GetLength(0); i++)
            {
                for (ushort j = 0; j < Cells.GetLength(1); j++)
                {
                    for (ushort k = 0; k < Cells.GetLength(2); k++)
                    {
                        Cells[i, j, k] = new CAGraphCell(this, new ValueTuple<ushort, ushort, ushort>(i, j, k));
                    }
                }
            }
        }

        public CAGraph(CA parent, ValueTuple<ushort, ushort, ushort> size, GridShape shape, List<ValueTuple<ushort, ushort, ushort>> agents, CAGraphCell[,,] cells, Dictionary<string, dynamic> properties) : base(CAEntityType.Graph, properties)
        {
            Parent = parent;
            Shape = shape;
            AgentCells = agents.ConvertAll(x => new ValueTuple<ushort, ushort, ushort>(x.Item1, x.Item2, x.Item3));
            Updates = new List<ValueTuple<ushort, ushort, ushort>>();
            Dimensions = new ValueTuple<ushort, ushort, ushort>(size.Item1, size.Item2, size.Item3);
            Cells = new CAGraphCell[size.Item1, size.Item2, size.Item3];
            for (ushort i = 0; i < size.Item1; i++)
            {
                for (ushort j = 0; j < size.Item2; j++)
                {
                    for (ushort k = 0; k < size.Item3; k++)
                    {
                        //if(i == 500 && j == 500)
                        //{
                        //    Console.WriteLine();
                        //}
                        Cells[i, j, k] = cells[i, j, k].Copy(this);
                    }
                }
            }
        }
    }

    public class CAGraphCell:CAEntity
    {
        public CAGraph Parent { get; set; }
        public CAGraphCellAgent Agent { get; private set; }
        public ValueTuple<ushort, ushort, ushort> Position { get; private set; }
        //private Tuple<ushort, ushort, ushort>[][] Neighbors { get; set; }
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraphCell(CAGraph parent, ValueTuple<ushort, ushort, ushort> position):base(CAEntityType.Cell)
        {
            this.Parent = parent;
            this.Position = position;
            //this.Neighbors = new Tuple<ushort, ushort, ushort>[Enum.GetNames(typeof(CANeighborhoodType)).Count()][];
        }

        public CAGraphCell(CAGraph parent, ValueTuple<ushort, ushort, ushort> position, Dictionary<string, dynamic> properties, CAGraphCellAgent agent) :base(CAEntityType.Cell, properties)
        {
            this.Parent = parent;
            this.Position = position;
            if(agent != null)
            {
                this.Agent = agent.Copy(this);
            }
        }
    }

    public class CAGraphCellAgent:CAEntity
    {
        // have to change...this has to be a property? Or no, it's a CAEntity which has a list of CAProperties.
        //public int State { get; set; }
        public CAGraphCell Parent { get; set; }
        //System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

        public CAGraphCellAgent(CAGraphCell parent, ushort state):base(CAEntityType.Agent)
        {
            this.Parent = parent;
            AddProperty(("state", state));
        }

        public CAGraphCellAgent(CAGraphCell parent, Dictionary<string, dynamic> properties) :base(CAEntityType.Agent, properties)
        {
            this.Parent = parent;
        }
    }

Body:
It sounds like your problem is that your representation of your agents (using dictionaries) consumes too much memory.  If so, the solution is to find a more compact representation.

Since you're working in an object-oriented language, the typical solution would be to define an Agent class, possibly with subclasses for different types of agents, and use instance variables to store the state of each agent.  Then your CA grid will be an array of Agent instances (or possibly nulls for vacant cells).  This will be a lot more compact than using dictionaries with string keys.

Also, I would recommend not storing the position of the agent on the grid as part of the agent's state, but passing it as a parameter to any methods that need it.  Not only does this save a bit of memory just by itself, but it also allows you to place references to the same Agent instance at multiple cells on the grid to represent multiple identical agents.  Depending on how often such identical agents occur in your CA, this may save a huge amount of memory.

Note that, if you modify the state of such a reused agent instance, the modification will obviously affect all agents on the grid represented by that instance.  For that reason, it may be a good idea to make your Agent objects immutable and just create a new one whenever the agent's state changes.

You might also want to consider maintaining a cache (e.g. a set) of Agent instances already on the grid so that you can easily check if a new agent might be identical with an existing one.  Whether this will actually do any good depends on your specific CA model — with some CA you might be able to handle de-duplication sufficiently well even without such a cache (it's perfectly OK to have some duplicate Agent objects), while for others there might simply not be enough identical agents to make it worthwhile.  Also, if you do try this, note that you'll need to either design the cache to use weak references (which can be tricky to get right) or periodically purge and rebuild it to avoid old Agent objects lingering in the cache even after they've been removed from the grid.

Addendum based on your comment below, which I'll quote here:

Imagine an environment where the temperature varies seasonally (so a property on the graph). There are land and water cells (so properties on cells), and in low enough temperatures the water cells become frozen so animal agents can use them to cross over between land locations. Imagine those animal agents hunt other animal agents to eat them (so properties on the agents). Imagine the animal agents that get eaten eat trees (so other agents with properties), and tend to eat young saplings (limiting tree growth), thereby limiting their own growth (and that of the carnivore agents).

OK, so let's sketch out the classes you'd need.  (Please excuse any syntax errors; I'm not really a C# programmer and I haven't actually tested this code.  Just think of it as C#-like pseudocode or something.)

First of all, you will obviously need a bunch of agents.  Let's define an abstract superclass for them:

public abstract class Agent {
    public abstract void Act(Grid grid, int x, int y, float time);
}

Our CA simulation (which, for simplicity, I'm going to assume to be stochastic, i.e. one where the agents act one at a time in a random order, like in the Gillespie algorithm) is basically going to involve repeatedly picking a random cell (x, y) on the grid, checking if that cell contains an agent, and if so, calling Act() on that agent.  (We'll also need to update any time-dependent global state while we're doing that, but let's leave that for later.)

The Act() methods for the agents will receive a reference to the grid object, and can call its methods to make changes to the state of nearby cells (or even get a reference to the agents in those cells and call their methods directly).  This could involve e.g. removing another agent from the grid (because it just got eaten), adding a new agent (reproduction), changing the acting agent's location (movement) or even removing that agent from the grid (e.g. because it starved or died of old age).  For illustration, let's sketch a few agent classes:

public class Sapling : Agent {
    private static readonly double MATURATION_TIME = 10;  // arbitrary time delay

    private double birthTime;  // could make this a float to save memory
    public Sapling(double time) => birthTime = time;

    public override void Act(Grid grid, int x, int y, double time) {
        // if the sapling is old enough, it replaces itself with a tree
        if (time >= birthTime + MATURATION_TIME) {
            grid.SetAgentAt(x, y, Tree.INSTANCE);
        }
    }
}

public class Tree : Agent {
    public static readonly Tree INSTANCE = new Tree();

    public override void Act(Grid grid, int x, int y, double time) {
        // trees create saplings in nearby land cells
        (int x2, int y2) = grid.RandomNeighborOf(x, y);
        if (grid.GetAgentAt(x2, y2) == null && grid.CellTypeAt(x2, y2) == CellType.Land) {
            grid.SetAgentAt(x2, y2, new Sapling(time));
        }
    }
}

For the sake of brevity, I'll leave the implementation of the animal agents as an exercise.  Also, the Tree and Sapling implementations above are kind of crude and could be improved in various ways, but they should at least illustrate the concept.

One thing worth noting is that, to minimize memory usage, the agent classes above have as little internal state as possible.  In particular, the agents don't store their own location on the grid, but will receive it as arguments to the act() method.  Since omitting the location in fact made my Tree class completely stateless, I went ahead and used the same global Tree instance for all trees on the grid!  While this won't always be possible, when it is, it can save a lot of memory.

Now, what about the grid?  A basic implementation (ignoring the different cell types for a moment) would look something like this:

public class Grid {
    private readonly int width, height;
    private readonly Agent?[,] agents;

    public Grid(int w, int h) {
        width = w;
        height = h;
        agents = new Agent?[w, h];
    }

    // TODO: handle grid edges
    public Agent? GetAgentAt(int x, int y) => agents[x, y];
    public void SetAgentAt(int x, int y, Agent? agent) => agents[x, y] = agent;
}

Now, what about the cell types?  You have a couple of ways to handle those.

One way would be to make the grid store an array of Cell objects instead of agents, and have each cell store its state and (possibly) an agent.  But for optimizing memory use it's probably better to just have a separate 2D array storing the cell types, something like this:

public enum CellType : byte { Land, Water, Ice }

public class Grid {
    private readonly Random rng = new Random();
    private readonly int width, height;
    private readonly Agent?[,] agents;
    private readonly CellType[,] cells;  // TODO: init in constructor?

    private float temperature = 20;  // global temperature in Celsius

    // ...

    public CellType CellTypeAt(int x, int y) {
        CellType type = cells[x,y];
        if (type == CellType.Water && temperature < 0) return CellType.Ice;
        else return type;
    }
}

Note how the CellType enum is byte-based, which should keep the array storing them a bit more compact than if they were int-based.

Now, let's finally look at the main CA simulation loop.  At its most basic, it could look like this:

Grid grid = new Grid(width, height);
grid.SetAgentAt(width / 2, height / 2, Tree.INSTANCE);

// average simulation time per loop iteration, assuming that each
// actor on the grid acts once per unit time step on average
double dt = 1 / (width * height);

for (double t = 0; t < maxTime; t += dt) {
    (int x, int y) = grid.GetRandomLocation();
    Agent? agent = grid.GetAgentAt(x, y);
    if (agent != null) agent.Act(grid, x, y, t);
    // TODO: update temperature here?
}

(Technically, to correctly implement the Gillespie algorithm, the simulation time increment between iterations should be an exponentially distributed random number with mean dt, not a constant increment.  However, since only the actor on one of the width * height cells is chosen in each iteration, the number of iterations between actions by the same actor is geometrically distributed with mean width * height, and multiplying this by dt = 1 / (width * height) gives an excellent approximation for an exponential distribution with mean 1.  Which is a long-winded way of saying that in practice using a constant time step is perfectly fine.)

Since this is getting long enough, I'll let you continue from here.  I'll just note that there are plenty of ways to further expand and/or optimize the algorithm I've sketched above.

For example, you could speed up the simulation by maintaining a list of all grid locations that contain a live actor and randomly sampling actors from that list (but then you'd also need to scale the time step by the inverse of the length of the list).  Also, you may decide that you want some actors to get more frequent chances to act than others; while the simple way to do that is just to use rejection sampling (i.e. have the actor only do something if rng.Sample() < prob for some prob between 0 and 1), a more efficient way would be to maintain multiple lists of locations depending on the type of the actor there.


来源: stackexchange

问:
Evaluate different layout algorithms / interaction with graphs
I have to write a report on the following question:

Evaluate different layout algorithms / interaction with graphs

Where can I find useful resource to understand graph layout algorithms?

I have no experience in graph programming or visualisation, so resources starting from basics would be very helpful.

Thank You

答:
You might want to check the extensive documentation of the igraph software, which has some description of its internal layout generators. There are also nice illustrations on aiSee website.

For more academic reference, I would suggest browsing the following tutorials: Graph Drawing Tutorial (106 pages) or Graph and Network Visualization (69 pages).

Another useful resource: Handbook of Graph Drawing and Visualization (26 chapters, available as PDF).

ContentLicense: CC BY-SA 3.0


问:
On demand resources functionality iOS
Please advise with the below.

we are building iOS app using ODR, though I have few below questions. Request your assistance.

How do we provide a prompt to download the game from the application?
Context - We have total 25 games in our app and player can download one game at a time to play/try. Once done, user can download the   other game.

Can we send a user setting to download over wifi only vs wifi and data?

3.What will happen if the user doesn't have enough storage on the device?

Can the user clear games easily from their local storage?

If the app is forcibly closed during the download, will it again start downloading when the app is reopened?

Your help is much appreciated. Thanks very much.

Regards

答:
How do we provide a prompt to download the game from the application?

The user doesn't cause a download to happen; you do, by asking for access to the resource. As for your app talking to the user, it's no different from putting up any other kind of prompt, if that's what you want to do: You can ask the user (using an alert or whatever interface you like) what to do, and if the user wants a resource, you request access to it.

Can we send a user setting to download over wifi only vs wifi and data?

No. The user can decide whether your app can use Cellular data.

What will happen if the user doesn't have enough storage on the device?

I don't know, but maybe if you are downloading from Apple, the App Store is able to negotiate this with your app because it knows the size of the resource to be downloaded.

Can the user clear games easily from their local storage?

No. The user has no access to what's going on behind the scenes. Neither does your app; you have no way of forcing a no-longer-needed resource to be deleted immediately. If you don't need a resource, you signal that by ceasing to ask for access to it. When the system needs the space, it will do the deleting.

If the app is forcibly closed during the download, will it again start downloading when the app is reopened?

Not by magic, no. But the case is no different from a resource  that has been downloaded. It is always up to you to ask for access to a resource that you need, when you need it. It doesn’t matter whether the resource has been downloaded, partially downloaded, or not downloaded at all; what you do is always the same: you ask for access.  If the resource you're asking for is present, you get access immediately. If not, then the download is performed in response to the request.

ContentLicense: CC BY-SA 4.0

Title: On demand resources functionality iOS


问:
Accessing the second element of a list for every row in pandas dataframe
My data consist of Latitude in object type :

```<code>0        4.620881605
1        4.620124518
2        4.619367709
3        4.618609512
4         4.61784758
</code>```

Then, I split after the decimal point using this code:

```<code>marker['Latitude'].str.split('.')
</code>```

Resulting in :

```<code>0        [4, 620881605]
1        [4, 620124518]
2        [4, 619367709]
3        [4, 618609512]
4         [4, 61784758]
</code>```

which is good but not quite there yet. I want to access the second element of the list for every row and the end result I am expecting is this :

```<code>0        620881605
1        620124518
2        619367709
3        618609512
4         61784758
</code>```

答:
You can use pd.DataFrame.iterrows() to iterate by row and then select the proper index for your list.

```<code>import pandas as pd

x = pd.DataFrame({'a':[[1,2],[3,4],[5,6]]})

for index, row in x.iterrows():
    print(row['a'][1])

2
4
6
</code>```

Body:
My data consist of Latitude in object type :

0        4.620881605
1        4.620124518
2        4.619367709
3        4.618609512
4         4.61784758

Then, I split after the decimal point using this code:

marker['Latitude'].str.split('.')

Resulting in :

0        [4, 620881605]
1        [4, 620124518]
2        [4, 619367709]
3        [4, 618609512]
4         [4, 61784758]

which is good but not quite there yet. I want to access the second element of the list for every row and the end result I am expecting is this :

0        620881605
1        620124518
2        619367709
3        618609512
4         61784758

Body:
You can use pd.DataFrame.iterrows() to iterate by row and then select the proper index for your list.

import pandas as pd

x = pd.DataFrame({'a':[[1,2],[3,4],[5,6]]})

for index, row in x.iterrows():
    print(row['a'][1])

2
4
6


问:
Is there any way the removal of a cell doesn't refresh the entire listview?
I use two JavaFX Timeline objects to create a countdown timer and a progress bar (i.e. a shrinking JavaFX Rectangle) inside of a ListCell.  When the timer reaches zero, the width of the rectangle becomes zero and the cell is removed from the ListView.  However, the entire ListView is automatically refreshed causing the Timeline in the other cell to reset.  Here is what it looks like starting with two cells:

In the code, the updateItem method gets the number of seconds from the model and sets the text for the timer label.  When a cell is removed from the ListView, updateItem is called with a CellData object containing the string "20" which resets the timeline.  But I want the cell with the unfinished timer to continue; not start from the beginning.  Here's the minimum, reproducible example:

```<code>public class AnimatedCells extends Application {
public class MyCell extends ListCell<CellData> {
    private CellComponent cc;
    private Timeline rectTimeline, timerTimeline;
    private KeyValue rectWidth;

    public MyCell() {
        cc = new CellComponent();
        rectTimeline = new Timeline();
        timerTimeline = new Timeline();
        rectWidth = new KeyValue( cc.getRect().widthProperty(), 0 );
    }

    @Override
    protected void updateItem( CellData item, boolean empty ) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            if ( item.getData() != null ) {
                System.out.println(item.getData());

                cc.getTimer().setText( item.getData() );

                rectTimeline.getKeyFrames().add( new KeyFrame( Duration.seconds( Double.parseDouble( cc.getTimer().getText() ) ), rectWidth ) );
                timerTimeline.getKeyFrames().addAll(
                        new KeyFrame( Duration.seconds( 0 ),
                            event -> {
                                int timerSeconds = Integer.parseInt( cc.getTimer().getText() );

                                if ( timerSeconds > 0 ) {
                                    cc.getTimer().setText( Integer.toString(--timerSeconds) );
                                }
                                else {
                                    rectTimeline.stop();
                                    timerTimeline.stop();
                                    super.getListView().getItems().remove(this.getItem());
                                }
                        }),
                        new KeyFrame( Duration.seconds( 1 ) ) );
                timerTimeline.setCycleCount( Animation.INDEFINITE );
                setGraphic( cc.getCellPane() );
                rectTimeline.play();
                timerTimeline.play();
            }
        }
    }
}

public class CellComponent {
    @FXML
    private Pane cellPane;

    @FXML
    private Label timer;

    @FXML
    private Rectangle rect;

    public CellComponent() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listcell.fxml"));
        fxmlLoader.setController(this);
        try
        {
            fxmlLoader.load();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    public Pane getCellPane() {
        return cellPane;
    }

    public void setCellPane(Pane cellPane) {
        this.cellPane = cellPane;
    }

    public Label getTimer() {
        return timer;
    }

    public void setTimer(Label timer) {
        this.timer = timer;
    }

    public Rectangle getRect() {
        return rect;
    }

    public void setRect(Rectangle rect) {
        this.rect = rect;
    }

}

public class CellData {
    private String data;

    public CellData() {
        super();
    }

    public CellData(String data) {
        super();
        this.setData(data);
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

}

@FXML
private ListView<CellData> listView;

private ObservableList<CellData> observableList = FXCollections.observableArrayList();

public void initialize() {
    observableList.add( new CellData("20") );
    observableList.add( new CellData("10") );

    listView.setItems( observableList );
    listView.setCellFactory( listView -> {
        MyCell cell = new MyCell();
        return cell;
    });
}

@Override
public void start(Stage stage) throws Exception {
    Parent root = new FXMLLoader(getClass().getResource("/fxml/listmanager.fxml")).load();
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}

}
</code>```

Also, why is updateItem called three times on startup when there are only two rows of data?  The lone print statement in the above code outputs:

20

20

10

I am using Java 11.0.6.

答:
A Cell’s job is to determine how to display data.  The underlying data must not be changed in the Cell’s updateItem method, because a single Cell instance can be used for multiple values.

From the documentation for Cell:

Because TreeView, ListView, TableView and other such controls can potentially be used for displaying incredibly large amounts of data, it is not feasible to create an actual Cell for every single item in the control. We represent extremely large data sets using only very few Cells. Each Cell is "recycled", or reused.

You will need to move all Timelines into the CellData object.  And the Cell must not modify those Timelines, or the ListView’s items.

It’s customary, and useful, to make data objects have observable properties, so visual components can bind visual properties to them.

The CellData objects shouldn’t know about the ListView that contains them.  You can give each CellData instance a Consumer or other function which does the work of removing the data.

So, you’ll want something like this for the data class:

```<code>public static class CellData {
    private final StringProperty data;

    private final ReadOnlyDoubleWrapper secondsRemaining;

    private final Timeline timeline = new Timeline();

    public CellData(Consumer<? super CellData> finished) {
        data = new SimpleStringProperty(this, "data");
        secondsRemaining =
            new ReadOnlyDoubleWrapper(this, "secondsRemaining");

        data.addListener((o, oldData, newData) -> {
            try {
                double startTime = Double.parseDouble(newData);

                timeline.stop();

                timeline.getKeyFrames().setAll(
                    new KeyFrame(Duration.ZERO,
                        new KeyValue(secondsRemaining, startTime)),
                    new KeyFrame(Duration.seconds(startTime),
                        new KeyValue(secondsRemaining, 0.0))
                );
                timeline.setOnFinished(e -> finished.accept(this));

                timeline.play();
            } catch (NumberFormatException e) {
                System.err.println(
                    "Cannot start timer for invalid seconds value: " + e);
                Platform.runLater(() -> finished.accept(this));
            }
        });
    }

    public CellData(String data,
                    Consumer<? super CellData> finished) {
        this(finished);
        this.setData(data);
    }

    public StringProperty dataProperty() {
        return data;
    }

    public String getData() {
        return data.get();
    }

    public void setData(String data) {
        this.data.set(data);
    }

    public ReadOnlyDoubleProperty secondsRemainingProperty() {
        return secondsRemaining.getReadOnlyProperty();
    }

    public double getSecondsRemaining() {
        return secondsRemaining.get();
    }
}
</code>```

An instance would be constructed with something like this:

```<code>new CellData(secondsText,
    c -> list.getItems().remove(c)));
</code>```

This allows the cell class to be much simpler:

```<code>public static class MyCell extends ListCell<CellData> {
    private CellComponent cc;

    public MyCell() {
        cc = new CellComponent();
    }

    @Override
    protected void updateItem(CellData item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            cc.getTimer().textProperty().unbind();
            cc.getTimer().textProperty().bind(
                item.secondsRemainingProperty().asString("%.0f"));

            cc.getRect().widthProperty().unbind();
            cc.getRect().widthProperty().bind(
                item.secondsRemainingProperty().multiply(10));

            setText(null);
            setGraphic(cc.getCellPane());
        }
    }
}
</code>```

Putting it all together looks like this.  (For simplicity and reproducibility, I have replaced the FXML with inline code.)

```<code>import java.util.function.Consumer;

import javafx.application.Application;
import javafx.application.Platform;

import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;

import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper;

import javafx.geometry.Insets;
import javafx.geometry.Pos;

import javafx.stage.Stage;
import javafx.scene.Scene;

import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;

import javafx.scene.shape.Rectangle;

import javafx.util.Duration;
import javafx.util.converter.DoubleStringConverter;

public class AnimatedCells
extends Application {
    @Override
    public void start(Stage stage) {
        ListView<CellData> list = new ListView<>();
        list.setCellFactory(l -> new MyCell());

        TextField secondsField = new TextField();

        Button newTimerButton = new Button("Create");
        newTimerButton.setOnAction(e -> {
            list.getItems().add(
                new CellData(secondsField.getText(),
                    c -> list.getItems().remove(c)));
        });
        secondsField.setOnAction(e -> {
            list.getItems().add(
                new CellData(secondsField.getText(),
                    c -> list.getItems().remove(c)));
        });

        HBox newButtonPane = new HBox(6, secondsField, newTimerButton);
        newButtonPane.setPadding(new Insets(12));

        stage.setScene(new Scene(
            new BorderPane(list, null, null, newButtonPane, null)));
        stage.setTitle("Animated Cells");
        stage.show();
    }

    public static class MyCell extends ListCell<CellData> {
        private CellComponent cc;

        public MyCell() {
            cc = new CellComponent();
        }

        @Override
        protected void updateItem(CellData item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setText(null);
                setGraphic(null);
            } else {
                cc.getTimer().textProperty().unbind();
                cc.getTimer().textProperty().bind(
                    item.secondsRemainingProperty().asString("%.0f"));

                cc.getRect().widthProperty().unbind();
                cc.getRect().widthProperty().bind(
                    item.secondsRemainingProperty().multiply(10));

                setText(null);
                setGraphic(cc.getCellPane());
            }
        }
    }

    public static class CellData {
        private final StringProperty data;

        private final ReadOnlyDoubleWrapper secondsRemaining;

        private final Timeline timeline = new Timeline();

        public CellData(Consumer<? super CellData> finished) {
            data = new SimpleStringProperty(this, "data");
            secondsRemaining =
                new ReadOnlyDoubleWrapper(this, "secondsRemaining");

            data.addListener((o, oldData, newData) -> {
                try {
                    double startTime = Double.parseDouble(newData);

                    timeline.stop();

                    timeline.getKeyFrames().setAll(
                        new KeyFrame(Duration.ZERO,
                            new KeyValue(secondsRemaining, startTime)),
                        new KeyFrame(Duration.seconds(startTime),
                            new KeyValue(secondsRemaining, 0.0))
                    );
                    timeline.setOnFinished(e -> finished.accept(this));

                    timeline.play();
                } catch (NumberFormatException e) {
                    System.err.println(
                        "Cannot start timer for invalid seconds value: " + e);
                    Platform.runLater(() -> finished.accept(this));
                }
            });
        }

        public CellData(String data,
                        Consumer<? super CellData> finished) {
            this(finished);
            this.setData(data);
        }

        public StringProperty dataProperty() {
            return data;
        }

        public String getData() {
            return data.get();
        }

        public void setData(String data) {
            this.data.set(data);
        }

        public ReadOnlyDoubleProperty secondsRemainingProperty() {
            return secondsRemaining.getReadOnlyProperty();
        }

        public double getSecondsRemaining() {
            return secondsRemaining.get();
        }
    }

    public static class CellComponent {
        private final Pane cellPane;

        private final Label timer;

        private final Rectangle rect;

        public CellComponent() {
            // For the sake of example, I'm building this in code rather than
            // with FXML.

            //FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listcell.fxml"));
            //fxmlLoader.setController(this);
            //try
            //{
            //    fxmlLoader.load();
            //}
            //catch (IOException e)
            //{
            //    throw new RuntimeException(e);
            //}

            rect = new Rectangle(1, 40);
            rect.setArcWidth(20);
            rect.setArcHeight(20);
            rect.setStyle(
                "-fx-fill: red; -fx-stroke: black; -fx-stroke-width: 2;");
            timer = new Label(" ");
            timer.setStyle("-fx-font-size: 18pt; -fx-alignment: center;");
            cellPane = new HBox(24, timer, rect);
            cellPane.setStyle("-fx-alignment: center-left;");
        }

        public Pane getCellPane() {
            return cellPane;
        }

        public Label getTimer() {
            return timer;
        }

        public Rectangle getRect() {
            return rect;
        }
    }

    public static class Main {
        public static void main(String[] args) {
            Application.launch(AnimatedCells.class, args);
        }
    }
}
</code>```

Body:
I use two JavaFX Timeline objects to create a countdown timer and a progress bar (i.e. a shrinking JavaFX Rectangle) inside of a ListCell.  When the timer reaches zero, the width of the rectangle becomes zero and the cell is removed from the ListView.  However, the entire ListView is automatically refreshed causing the Timeline in the other cell to reset.  Here is what it looks like starting with two cells:

In the code, the updateItem method gets the number of seconds from the model and sets the text for the timer label.  When a cell is removed from the ListView, updateItem is called with a CellData object containing the string "20" which resets the timeline.  But I want the cell with the unfinished timer to continue; not start from the beginning.  Here's the minimum, reproducible example:

public class AnimatedCells extends Application {
public class MyCell extends ListCell<CellData> {
    private CellComponent cc;
    private Timeline rectTimeline, timerTimeline;
    private KeyValue rectWidth;

    public MyCell() {
        cc = new CellComponent();
        rectTimeline = new Timeline();
        timerTimeline = new Timeline();
        rectWidth = new KeyValue( cc.getRect().widthProperty(), 0 );
    }

    @Override
    protected void updateItem( CellData item, boolean empty ) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            if ( item.getData() != null ) {
                System.out.println(item.getData());

                cc.getTimer().setText( item.getData() );

                rectTimeline.getKeyFrames().add( new KeyFrame( Duration.seconds( Double.parseDouble( cc.getTimer().getText() ) ), rectWidth ) );
                timerTimeline.getKeyFrames().addAll(
                        new KeyFrame( Duration.seconds( 0 ),
                            event -> {
                                int timerSeconds = Integer.parseInt( cc.getTimer().getText() );

                                if ( timerSeconds > 0 ) {
                                    cc.getTimer().setText( Integer.toString(--timerSeconds) );
                                }
                                else {
                                    rectTimeline.stop();
                                    timerTimeline.stop();
                                    super.getListView().getItems().remove(this.getItem());
                                }
                        }),
                        new KeyFrame( Duration.seconds( 1 ) ) );
                timerTimeline.setCycleCount( Animation.INDEFINITE );
                setGraphic( cc.getCellPane() );
                rectTimeline.play();
                timerTimeline.play();
            }
        }
    }
}

public class CellComponent {
    @FXML
    private Pane cellPane;

    @FXML
    private Label timer;

    @FXML
    private Rectangle rect;

    public CellComponent() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listcell.fxml"));
        fxmlLoader.setController(this);
        try
        {
            fxmlLoader.load();
        }
        catch (IOException e)
        {
            throw new RuntimeException(e);
        }
    }

    public Pane getCellPane() {
        return cellPane;
    }

    public void setCellPane(Pane cellPane) {
        this.cellPane = cellPane;
    }

    public Label getTimer() {
        return timer;
    }

    public void setTimer(Label timer) {
        this.timer = timer;
    }

    public Rectangle getRect() {
        return rect;
    }

    public void setRect(Rectangle rect) {
        this.rect = rect;
    }

}

public class CellData {
    private String data;

    public CellData() {
        super();
    }

    public CellData(String data) {
        super();
        this.setData(data);
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

}

@FXML
private ListView<CellData> listView;

private ObservableList<CellData> observableList = FXCollections.observableArrayList();

public void initialize() {
    observableList.add( new CellData("20") );
    observableList.add( new CellData("10") );

    listView.setItems( observableList );
    listView.setCellFactory( listView -> {
        MyCell cell = new MyCell();
        return cell;
    });
}

@Override
public void start(Stage stage) throws Exception {
    Parent root = new FXMLLoader(getClass().getResource("/fxml/listmanager.fxml")).load();
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}

}

Also, why is updateItem called three times on startup when there are only two rows of data?  The lone print statement in the above code outputs:

20

20

10

I am using Java 11.0.6.

Body:
A Cell’s job is to determine how to display data.  The underlying data must not be changed in the Cell’s updateItem method, because a single Cell instance can be used for multiple values.

From the documentation for Cell:

Because TreeView, ListView, TableView and other such controls can potentially be used for displaying incredibly large amounts of data, it is not feasible to create an actual Cell for every single item in the control. We represent extremely large data sets using only very few Cells. Each Cell is "recycled", or reused.

You will need to move all Timelines into the CellData object.  And the Cell must not modify those Timelines, or the ListView’s items.

It’s customary, and useful, to make data objects have observable properties, so visual components can bind visual properties to them.

The CellData objects shouldn’t know about the ListView that contains them.  You can give each CellData instance a Consumer or other function which does the work of removing the data.

So, you’ll want something like this for the data class:

public static class CellData {
    private final StringProperty data;

    private final ReadOnlyDoubleWrapper secondsRemaining;

    private final Timeline timeline = new Timeline();

    public CellData(Consumer<? super CellData> finished) {
        data = new SimpleStringProperty(this, "data");
        secondsRemaining =
            new ReadOnlyDoubleWrapper(this, "secondsRemaining");

        data.addListener((o, oldData, newData) -> {
            try {
                double startTime = Double.parseDouble(newData);

                timeline.stop();

                timeline.getKeyFrames().setAll(
                    new KeyFrame(Duration.ZERO,
                        new KeyValue(secondsRemaining, startTime)),
                    new KeyFrame(Duration.seconds(startTime),
                        new KeyValue(secondsRemaining, 0.0))
                );
                timeline.setOnFinished(e -> finished.accept(this));

                timeline.play();
            } catch (NumberFormatException e) {
                System.err.println(
                    "Cannot start timer for invalid seconds value: " + e);
                Platform.runLater(() -> finished.accept(this));
            }
        });
    }

    public CellData(String data,
                    Consumer<? super CellData> finished) {
        this(finished);
        this.setData(data);
    }

    public StringProperty dataProperty() {
        return data;
    }

    public String getData() {
        return data.get();
    }

    public void setData(String data) {
        this.data.set(data);
    }

    public ReadOnlyDoubleProperty secondsRemainingProperty() {
        return secondsRemaining.getReadOnlyProperty();
    }

    public double getSecondsRemaining() {
        return secondsRemaining.get();
    }
}

An instance would be constructed with something like this:

new CellData(secondsText,
    c -> list.getItems().remove(c)));

This allows the cell class to be much simpler:

public static class MyCell extends ListCell<CellData> {
    private CellComponent cc;

    public MyCell() {
        cc = new CellComponent();
    }

    @Override
    protected void updateItem(CellData item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setText(null);
            setGraphic(null);
        } else {
            cc.getTimer().textProperty().unbind();
            cc.getTimer().textProperty().bind(
                item.secondsRemainingProperty().asString("%.0f"));

            cc.getRect().widthProperty().unbind();
            cc.getRect().widthProperty().bind(
                item.secondsRemainingProperty().multiply(10));

            setText(null);
            setGraphic(cc.getCellPane());
        }
    }
}

Putting it all together looks like this.  (For simplicity and reproducibility, I have replaced the FXML with inline code.)

import java.util.function.Consumer;

import javafx.application.Application;
import javafx.application.Platform;

import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;

import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper;

import javafx.geometry.Insets;
import javafx.geometry.Pos;

import javafx.stage.Stage;
import javafx.scene.Scene;

import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;

import javafx.scene.shape.Rectangle;

import javafx.util.Duration;
import javafx.util.converter.DoubleStringConverter;

public class AnimatedCells
extends Application {
    @Override
    public void start(Stage stage) {
        ListView<CellData> list = new ListView<>();
        list.setCellFactory(l -> new MyCell());

        TextField secondsField = new TextField();

        Button newTimerButton = new Button("Create");
        newTimerButton.setOnAction(e -> {
            list.getItems().add(
                new CellData(secondsField.getText(),
                    c -> list.getItems().remove(c)));
        });
        secondsField.setOnAction(e -> {
            list.getItems().add(
                new CellData(secondsField.getText(),
                    c -> list.getItems().remove(c)));
        });

        HBox newButtonPane = new HBox(6, secondsField, newTimerButton);
        newButtonPane.setPadding(new Insets(12));

        stage.setScene(new Scene(
            new BorderPane(list, null, null, newButtonPane, null)));
        stage.setTitle("Animated Cells");
        stage.show();
    }

    public static class MyCell extends ListCell<CellData> {
        private CellComponent cc;

        public MyCell() {
            cc = new CellComponent();
        }

        @Override
        protected void updateItem(CellData item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setText(null);
                setGraphic(null);
            } else {
                cc.getTimer().textProperty().unbind();
                cc.getTimer().textProperty().bind(
                    item.secondsRemainingProperty().asString("%.0f"));

                cc.getRect().widthProperty().unbind();
                cc.getRect().widthProperty().bind(
                    item.secondsRemainingProperty().multiply(10));

                setText(null);
                setGraphic(cc.getCellPane());
            }
        }
    }

    public static class CellData {
        private final StringProperty data;

        private final ReadOnlyDoubleWrapper secondsRemaining;

        private final Timeline timeline = new Timeline();

        public CellData(Consumer<? super CellData> finished) {
            data = new SimpleStringProperty(this, "data");
            secondsRemaining =
                new ReadOnlyDoubleWrapper(this, "secondsRemaining");

            data.addListener((o, oldData, newData) -> {
                try {
                    double startTime = Double.parseDouble(newData);

                    timeline.stop();

                    timeline.getKeyFrames().setAll(
                        new KeyFrame(Duration.ZERO,
                            new KeyValue(secondsRemaining, startTime)),
                        new KeyFrame(Duration.seconds(startTime),
                            new KeyValue(secondsRemaining, 0.0))
                    );
                    timeline.setOnFinished(e -> finished.accept(this));

                    timeline.play();
                } catch (NumberFormatException e) {
                    System.err.println(
                        "Cannot start timer for invalid seconds value: " + e);
                    Platform.runLater(() -> finished.accept(this));
                }
            });
        }

        public CellData(String data,
                        Consumer<? super CellData> finished) {
            this(finished);
            this.setData(data);
        }

        public StringProperty dataProperty() {
            return data;
        }

        public String getData() {
            return data.get();
        }

        public void setData(String data) {
            this.data.set(data);
        }

        public ReadOnlyDoubleProperty secondsRemainingProperty() {
            return secondsRemaining.getReadOnlyProperty();
        }

        public double getSecondsRemaining() {
            return secondsRemaining.get();
        }
    }

    public static class CellComponent {
        private final Pane cellPane;

        private final Label timer;

        private final Rectangle rect;

        public CellComponent() {
            // For the sake of example, I'm building this in code rather than
            // with FXML.

            //FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/listcell.fxml"));
            //fxmlLoader.setController(this);
            //try
            //{
            //    fxmlLoader.load();
            //}
            //catch (IOException e)
            //{
            //    throw new RuntimeException(e);
            //}

            rect = new Rectangle(1, 40);
            rect.setArcWidth(20);
            rect.setArcHeight(20);
            rect.setStyle(
                "-fx-fill: red; -fx-stroke: black; -fx-stroke-width: 2;");
            timer = new Label(" ");
            timer.setStyle("-fx-font-size: 18pt; -fx-alignment: center;");
            cellPane = new HBox(24, timer, rect);
            cellPane.setStyle("-fx-alignment: center-left;");
        }

        public Pane getCellPane() {
            return cellPane;
        }

        public Label getTimer() {
            return timer;
        }

        public Rectangle getRect() {
            return rect;
        }
    }

    public static class Main {
        public static void main(String[] args) {
            Application.launch(AnimatedCells.class, args);
        }
    }
}


问:
Can't exec "/bin/sh": Argument list too long at perl
Below command in perl script is failing if there are many file in @file_to_tar, but it is working fine if we have less files in the array (@file_to_tar).

my $tar_command = "cd $ProcVars->{dropbox_dir}; tar -cvzf SmartMiles.$ProcVars->{batch_nb}.tar.gz -P @file_to_tar --remove-files";

Can some one please help me to fix the issue.

答: You might consider, rather than calling a shell command, using the Archive::Tar Perl module instead. In particular, the "create_archive" method. This also would sidestep any potential problems arising from special characters or whitespace in the file names being interpreted by the shell your Perl code is invoking.</p>


问:
How to make the history logs store in the spreadsheet?
I've created a simple counter which has a single textbox, disabled box and a history to record all previous value in the disabled box.

It works perfectly, but somehow when the page is accidentally refreshed all the logs are deleted.

Is there a way to keep that record even if the page reload? Or maybe store it in a spreadsheet?

CODE :

```<code>let box1 = document.getElementById("box1");
let box2 = document.getElementById("box2");
let resetBtn = document.getElementById("reset");
let historyContainer = document.getElementById("history");
let history = [];

//listen key enter press on the input
box1.addEventListener("keyup", e => {
  if (e.key === "Enter" && e.target.value !== "") {
  const summedValue = (box2.value && box2.value.trim() === "")  ? Number(box2.value) : Number(box2.value) + Number(e.target.value)
  box2.value = summedValue;
  historyContainer.innerHTML += `<p>${box2.value}</p>`;
  box1.value = "";
  }
});
//reset the second box and
resetBtn.addEventListener("click", () => {
  box2.value = "";
  historyContainer.innerHTML = ""
});
<input type="number" id="box1" />
<input type="number" id="box2" disabled />
<div id="history">
</div>

<button type="button" id="reset">
Reset
</button>
</code>```

答:
If you’re talking about storing it in the browser, without any server code, you should consider localStorage from the web storage API.

To save a value:

localStorage.setItem(‘box2’, ‘value of box 2’);
```

<p>To get it back:</p>

<pre class="lang-js prettyprint-override"><code>const value = localStorage.getItem(‘box2’);
</code>```

Here's a modified version of your code that saves the history to local storage and pre-populates it when it initially runs.

NOTE: The local storage code in this snippet doesn't work on Stack Overflow due to security restrictions, but hopefully you can still see
  how it works.

(() => {
  let box1 = document.getElementById("box1");
  let box2 = document.getElementById("box2");
  let resetBtn = document.getElementById("reset");
  let historyContainer = document.getElementById("history");
  let history = [];

  try {
    // pre-populate the history from local storage.
    // NOTE: this WILL NOT WORK on stack overflow due to security restrictions.
    const historyContent = localStorage.getItem('historyContent');
    historyContainer.innerHTML = historyContent;
  }
  catch (e) {
    console.log("can't load. can't access local storage:", e.message);
  }

  //listen key enter press on the input
  box1.addEventListener("keyup", e => {
    if (e.key === "Enter" && e.target.value !== "") {
      const summedValue = Number(box2.value.trim() || 0) + Number(e.target.value);
      box2.value = summedValue;
      historyContainer.innerHTML += `<p>${box2.value}</p>`;
      box1.value = "";

      try {
        // save new markup to local storage:
        // NOTE: this WILL NOT WORK on stack overflow due to security restrictions
        localStorage.setItem('historyContent', historyContainer.innerHTML);
      }
      catch (e) {
        console.log("can't save. can't access local storage:", e.message);
      }
    }
  });

  //reset the second box and
  resetBtn.addEventListener("click", () => {
    box2.value = "";
    historyContainer.innerHTML = "";

    // clear historyContent from localStorage
    localStorage.removeItem('historyContent');

    // or clear all local storage
    localStorage.clear();
  });
})();```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div>
  <input type="number" id="box1" />
  <input type="number" id="box2" disabled />
  <div id="history"></div>
  <button type="button" id="reset">Reset</button>
</div></code>```

Body:
I've created a simple counter which has a single textbox, disabled box and a history to record all previous value in the disabled box.

It works perfectly, but somehow when the page is accidentally refreshed all the logs are deleted.

Is there a way to keep that record even if the page reload? Or maybe store it in a spreadsheet?

CODE :

let box1 = document.getElementById("box1");
let box2 = document.getElementById("box2");
let resetBtn = document.getElementById("reset");
let historyContainer = document.getElementById("history");
let history = [];

//listen key enter press on the input
box1.addEventListener("keyup", e => {
  if (e.key === "Enter" && e.target.value !== "") {
  const summedValue = (box2.value && box2.value.trim() === "")  ? Number(box2.value) : Number(box2.value) + Number(e.target.value)
  box2.value = summedValue;
  historyContainer.innerHTML += `<p>${box2.value}</p>`;
  box1.value = "";
  }
});
//reset the second box and
resetBtn.addEventListener("click", () => {
  box2.value = "";
  historyContainer.innerHTML = ""
});
<input type="number" id="box1" />
<input type="number" id="box2" disabled />

<button type="button" id="reset">
Reset
</button>

Body:
If you’re talking about storing it in the browser, without any server code, you should consider localStorage from the web storage API.

To save a value:

localStorage.setItem(‘box2’, ‘value of box 2’);

To get it back:

const value = localStorage.getItem(‘box2’);

Here's a modified version of your code that saves the history to local storage and pre-populates it when it initially runs.

NOTE: The local storage code in this snippet doesn't work on Stack Overflow due to security restrictions, but hopefully you can still see
  how it works.

(() => {
  let box1 = document.getElementById("box1");
  let box2 = document.getElementById("box2");
  let resetBtn = document.getElementById("reset");
  let historyContainer = document.getElementById("history");
  let history = [];

  try {
    // pre-populate the history from local storage.
    // NOTE: this WILL NOT WORK on stack overflow due to security restrictions.
    const historyContent = localStorage.getItem('historyContent');
    historyContainer.innerHTML = historyContent;
  }
  catch (e) {
    console.log("can't load. can't access local storage:", e.message);
  }

  //listen key enter press on the input
  box1.addEventListener("keyup", e => {
    if (e.key === "Enter" && e.target.value !== "") {
      const summedValue = Number(box2.value.trim() || 0) + Number(e.target.value);
      box2.value = summedValue;
      historyContainer.innerHTML += `<p>${box2.value}</p>`;
      box1.value = "";

      try {
        // save new markup to local storage:
        // NOTE: this WILL NOT WORK on stack overflow due to security restrictions
        localStorage.setItem('historyContent', historyContainer.innerHTML);
      }
      catch (e) {
        console.log("can't save. can't access local storage:", e.message);
      }
    }
  });

  //reset the second box and
  resetBtn.addEventListener("click", () => {
    box2.value = "";
    historyContainer.innerHTML = "";

    // clear historyContent from localStorage
    localStorage.removeItem('historyContent');

    // or clear all local storage
    localStorage.clear();
  });
})();

<div>
  <input type="number" id="box1" />
  <input type="number" id="box2" disabled />
  <div id="history"></div>
  <button type="button" id="reset">Reset</button>
</div>


问:
How to remove TS2722: Cannot invoke an object which is possibly 'undefined'. error?
I have a function looking like this

```<code>let bcInst;
if(props.onBoundsChanged){
    bcInst = kakao.maps.event.addListener(map, 'bounds_changed',()=>{
        props.onBoundsChanged(map); //I get error here
    })
}
</code>```

props interface looking like below

```<code>interface IMapProps{
    mapId?: string;
    longitude: number;
    latitude: number;
    level:number;
    onBoundsChanged?:{
        (map:any) : void
    }
}
</code>```

Even if I am checking for props.onBoundsChanged in an if statement, I am getting TS2722: Cannot invoke an object which is possibly 'undefined'. error at the position I am using props.onBoundsChanged. How do I solve this issue?

答:
Because you event listener might be invoked much later than you have done the check, TypeScript is complaining

Fix

Store the reference that TypeScript knows to be valid e.g.

```<code>let bcInst;
if(props.onBoundsChanged){
    const {onBoundsChanged} = props; // STORE
    bcInst = kakao.maps.event.addListener(map, 'bounds_changed',()=>{
        onBoundsChanged(map); // OKAY
    })
}
</code>```

Alternatively move the check inside the listener.

Body:
I have a function looking like this

let bcInst;
if(props.onBoundsChanged){
    bcInst = kakao.maps.event.addListener(map, 'bounds_changed',()=>{
        props.onBoundsChanged(map); //I get error here
    })
}

props interface looking like below

interface IMapProps{
    mapId?: string;
    longitude: number;
    latitude: number;
    level:number;
    onBoundsChanged?:{
        (map:any) : void
    }
}

Even if I am checking for props.onBoundsChanged in an if statement, I am getting TS2722: Cannot invoke an object which is possibly 'undefined'. error at the position I am using props.onBoundsChanged. How do I solve this issue?

Body:
Because you event listener might be invoked much later than you have done the check, TypeScript is complaining

Fix

Store the reference that TypeScript knows to be valid e.g.

let bcInst;
if(props.onBoundsChanged){
    const {onBoundsChanged} = props; // STORE
    bcInst = kakao.maps.event.addListener(map, 'bounds_changed',()=>{
        onBoundsChanged(map); // OKAY
    })
}

Alternatively move the check inside the listener.


问:
Python json.loads fails with error- "simplejson.errors.JSONDecodeError: Invalid control character '\x00' at: line 1 column 536 (char 535)"
I have a json file and I am trying to load its contents line by line using json.loads command but I am getting below error-

"simplejson.errors.JSONDecodeError: Invalid control character '\x00' at: line 1 column 536 (char 535)"

Code snippet-

```<code>import simplejson as json
   with open(file_path) as file:
      for line in file:
         line_contents = json.loads(line)#.replace('\x00',' ')
</code>```

Note: I also tried replacing '\x00' with ' ' but it didn't help and threw another error-

"simplejson.errors.JSONDecodeError: Unterminated string starting at: line 1 column 163 (char 162)"

Any help would be appreciated!

答:
This happens a lot of times, depending on what environment your input file came from. Try this:</p>

```<code>import simplejson as json
   with open(file_path) as file:
      for line in file:
         line_contents = json.loads(line, strict=False)
</code>```

Body:
I have a json file and I am trying to load its contents line by line using json.loads command but I am getting below error-

"simplejson.errors.JSONDecodeError: Invalid control character '\x00' at: line 1 column 536 (char 535)"

Code snippet-

import simplejson as json
   with open(file_path) as file:
      for line in file:
         line_contents = json.loads(line)#.replace('\x00',' ')

Note: I also tried replacing '\x00' with ' ' but it didn't help and threw another error-

"simplejson.errors.JSONDecodeError: Unterminated string starting at: line 1 column 163 (char 162)"

Any help would be appreciated!

Body:
This happens a lot of times, depending on what environment your input file came from. Try this:

import simplejson as json
   with open(file_path) as file:
      for line in file:
         line_contents = json.loads(line, strict=False)


问:
Resetting array index when reaching the last index
I'm trying to build a code in which the 12 months of the calendar are in an array, the code then asks for a month, and then it outputs the 10 months ahead of the inputted month.

```<code>e.g.
input: January
output: February, March,...November
</code>```

I'm having trouble reverting the index back to the start once the index exceeds 12, for example, if I input August, it's supposed to output September to June, but instead it stops at December and says out of bounds. Thank you

```<code>   String months[];
   String choice;
   months = new String[13];
   months[0] = null ;
   months[1] = "January";
   months[2] = "February";
   months[3] = "March";
   months[4] = "April";
   months[5] = "May";
   months[6] = "June";
   months[7] = "July";
   months[8] = "August";
   months[9] = "September";
   months[10] = "October";
   months[11] = "November";
   months[12] = "December";
   System.out.print("Enter Month : ");
   choice = a.nextLine();

   if (choice.equals("August")) {
       for(int i=8; i<i+10; i++) {
           String result= months[i];
           System.out.println(result);
       }
   }
</code>```

答:
Use the modulus when choosing the month to print:

```<code>int start = 8;
if ("August".equals(choice)) {
    for(int i=start; i < start+10; i++) {
        String result= months[i % 12];
        System.out.println(result);
    }
}
</code>```

This assumes you have defined your months array as:

```<code>String[] months = new String[12];
months[0] = "January";
months[1] = "February";
// ...
months[11] = "December";
</code>```

The idea here is to wrap around the index used to select a month from the array.  The dummy variable i, upon hitting the value 12, will wrap around to zero again.

Side note: It is always better to compare a string literal to a variable by placing the literal on the LHS of the comparison.  The version I used is immune to a null pointer exception; the version you used is not.

Body:
I'm trying to build a code in which the 12 months of the calendar are in an array, the code then asks for a month, and then it outputs the 10 months ahead of the inputted month.

e.g.
input: January
output: February, March,...November

I'm having trouble reverting the index back to the start once the index exceeds 12, for example, if I input August, it's supposed to output September to June, but instead it stops at December and says out of bounds. Thank you

   String months[];
   String choice;
   months = new String[13];
   months[0] = null ;
   months[1] = "January";
   months[2] = "February";
   months[3] = "March";
   months[4] = "April";
   months[5] = "May";
   months[6] = "June";
   months[7] = "July";
   months[8] = "August";
   months[9] = "September";
   months[10] = "October";
   months[11] = "November";
   months[12] = "December";
   System.out.print("Enter Month : ");
   choice = a.nextLine();

   if (choice.equals("August")) {
       for(int i=8; i<i+10; i++) {
           String result= months[i];
           System.out.println(result);
       }
   }

Body:
Use the modulus when choosing the month to print:

int start = 8;
if ("August".equals(choice)) {
    for(int i=start; i < start+10; i++) {
        String result= months[i % 12];
        System.out.println(result);
    }
}

This assumes you have defined your months array as:

String[] months = new String[12];
months[0] = "January";
months[1] = "February";
// ...
months[11] = "December";

The idea here is to wrap around the index used to select a month from the array.  The dummy variable i, upon hitting the value 12, will wrap around to zero again.

Side note: It is always better to compare a string literal to a variable by placing the literal on the LHS of the comparison.  The version I used is immune to a null pointer exception; the version you used is not.


问:
Call to a member function getQuery() on null symfony
I'm following this tuto about CSV export on EasyAdmin bundle in symfony (link)
and I'm stuck at this point:

```<code>$queryBuilder = $this->createListQueryBuilder(

        Employee::class,
        $sortDirection,
        $this->request->query->get('sortField'),
        $this->entity['list']['dql_filter']
    );
        return $this->csvExporter->getResponseFromQueryBuilder(
        $queryBuilder,
        Employee::class,
        'employees.csv'
    );
</code>```

UPDATE:
I'm overwriting the method createListQueryBuilder

```<code>protected function createListQueryBuilder($entityClass, $sortDirection, $sortField = null   , $dqlFilter = null){}
</code>```

and in the csvExporter i'm defining a function getResponseFormQueryBuilder

```<code>public function getResponseFromQueryBuilder(QueryBuilder $queryBuilder, $columns, $filename)
</code>```

I'm having a bug that says that:

Expected parameter of type '\Doctrine\ORM\QueryBuilder', 'void' provided

答: you should make sure $queryBuilder is type of QueryBuilder , I advise you to trace debug $queryBuilder variable before return line and detect why it's void.

Body:
I'm following this tuto about CSV export on EasyAdmin bundle in symfony (link)
and I'm stuck at this point:

$queryBuilder = $this->createListQueryBuilder(

        Employee::class,
        $sortDirection,
        $this->request->query->get('sortField'),
        $this->entity['list']['dql_filter']
    );
        return $this->csvExporter->getResponseFromQueryBuilder(
        $queryBuilder,
        Employee::class,
        'employees.csv'
    );

UPDATE:
I'm overwriting the method createListQueryBuilder

protected function createListQueryBuilder($entityClass, $sortDirection, $sortField = null   , $dqlFilter = null){}

and in the csvExporter i'm defining a function getResponseFormQueryBuilder

public function getResponseFromQueryBuilder(QueryBuilder $queryBuilder, $columns, $filename)

I'm having a bug that says that:

Expected parameter of type '\Doctrine\ORM\QueryBuilder', 'void' provided


问:
Adding html code inside bootstrap-slider tooltip
I am using bootstrap-slider with a tooltip, is it possible to add html to this to format the content inside the tooltip? Currently, it only shows the value of the slider

I would like to add text above and below my value in different font sizes

```<code>var slider = new Slider('#l-calculator', {
  tooltip: 'always',
  formatter: function (value) {
    return '£' + value + '.00';
  }
});
</code>```

答:
Of course, it is possible! You just need a bit of help from JQuery and some CSS.

$(document).ready(function(){

//Insert the elements at the top and bottom
//in this case, each is a DIV with a class
//in the middle of both DIVs is the current content
$("div.tooltip-inner").html("
I'm on top
"+$("div.tooltip-inner").html() + "

I'm below
");

//To keep the Tooltip updated, we tied the change of the content to 2 events:
//'slide' (every time the handles are dragged) and 'slideStop'
//(when the handle is released)

$("#range").on("slide slideStop", function(slideEvt) {

//the action is the same as when we initiated the element, we replace
//all the content with the DIVs and the real content in the middle
$("div.tooltip-inner").html("
I'm on top
"+$("div.tooltip-inner").html() + "

I'm below
");

    });
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>/*Keep the Tooltip Visible and in a height above the slide bar*/
    .tooltip {
      opacity:0.9;
      top: -30px;
    }
/*Add custom color to the top and bottom DIVs: feel free to make your own here*/
    div.tooltip-inner .top {
      color: red !important;
      font-size:large;
      opacity: 0.9 !important;
    }

    div.tooltip-inner .bottom {
      color: blue !important;
      opacity: 0.9 !important;
    }</code>```

    <title>Bootstrap Slider</title>

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/10.0.0/css/bootstrap-slider.min.css">

      Range Slider with custom Tooltip
      <input id="range" type="text"/>

```

Body:
I am using bootstrap-slider with a tooltip, is it possible to add html to this to format the content inside the tooltip? Currently, it only shows the value of the slider

I would like to add text above and below my value in different font sizes

var slider = new Slider('#l-calculator', {
  tooltip: 'always',
  formatter: function (value) {
    return '£' + value + '.00';
  }
});

Body:
Of course, it is possible! You just need a bit of help from JQuery and some CSS.

$(document).ready(function(){

//Insert the elements at the top and bottom
//in this case, each is a DIV with a class
//in the middle of both DIVs is the current content
$("div.tooltip-inner").html("<div class='top'>I'm on top</div>"+$("div.tooltip-inner").html() + "<br><div class='bottom'>I'm below</div>");

//To keep the Tooltip updated, we tied the change of the content to 2 events:
//'slide' (every time the handles are dragged) and 'slideStop'
//(when the handle is released)

$("#range").on("slide slideStop", function(slideEvt) {

//the action is the same as when we initiated the element, we replace
//all the content with the DIVs and the real content in the middle
$("div.tooltip-inner").html("<div class='top'>I'm on top</div>"+$("div.tooltip-inner").html() + "<br><div class='bottom'>I'm below</div>");

    });
});

/*Keep the Tooltip Visible and in a height above the slide bar*/
    .tooltip {
      opacity:0.9;
      top: -30px;
    }
/*Add custom color to the top and bottom DIVs: feel free to make your own here*/
    div.tooltip-inner .top {
      color: red !important;
      font-size:large;
      opacity: 0.9 !important;
    }

    div.tooltip-inner .bottom {
      color: blue !important;
      opacity: 0.9 !important;
    }

<html>
  <head>
    <title>Bootstrap Slider</title>
    <script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/10.0.0/css/bootstrap-slider.min.css">
  </head>
  <body>
    <div class="jumbotron text-center">

      <br><br><br><br>

      <label>Range Slider with custom Tooltip</label>
      <input id="range" type="text"/>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/10.0.0/bootstrap-slider.min.js"></script>
    <script>

      // Range Slider
      var slider = new Slider("#range", {
        min: 0,
        max: 100,
        value: [50, 80],
        range: true,
        tooltip: 'always',
        formatter: function (a) {
            return Array.isArray(a) ? "£ "+ a[0] + ".00 to £ " + a[1] + ".00" : "£ "+a+".00"
        }
      });
    </script>
  </body>
</html>


问:
Could someone explain why my code is not working properly?
i am doing a challenge but for some reason every time i run it says 3 outta of 7 test cases are incorrect and don't know why? everything seems in order. Here is the challenge if Task
Given an integer, , perform the following conditional actions:

If  is odd, print Weird
If  is even and in the inclusive 2 range of 5 to , print Not Weird
If  is even and in the inclusive range of 6 to 20, print Weird
If  is even and greater than 20, print Not Weird

My code below:

```<code>n = int(input().strip())
if n % 2 != 0:
    print("Weird")
else:
    if n % 2 == 1 and n in range(2,5):
        print("Not Weird")

    elif n % 2 == 1 and n in range(6,20):
        print("Weird")

    elif n > 20:
        print("Not Weird")
</code>```

答:
To include 5 and 20 in range you need to specify it as number + 1. Range does not include the last number. Also, there is no need to check for even condition every time in the else part as the control jumps to else when if fails!.

```<code>n = int(input().strip())
if n % 2 != 0:
    print("Weird")
else:
    if n in range(2,6):
        print("Not Weird")

    elif n in range(6,21):
        print("Weird")

    elif n > 20:
        print("Not Weird")
</code>```

Body:
i am doing a challenge but for some reason every time i run it says 3 outta of 7 test cases are incorrect and don't know why? everything seems in order. Here is the challenge if Task
Given an integer, , perform the following conditional actions:

If  is odd, print Weird
If  is even and in the inclusive 2 range of 5 to , print Not Weird
If  is even and in the inclusive range of 6 to 20, print Weird
If  is even and greater than 20, print Not Weird

My code below:

n = int(input().strip())
if n % 2 != 0:
    print("Weird")
else:
    if n % 2 == 1 and n in range(2,5):
        print("Not Weird")

    elif n % 2 == 1 and n in range(6,20):
        print("Weird")

    elif n > 20:
        print("Not Weird")

Body:
To include 5 and 20 in range you need to specify it as number + 1. Range does not include the last number. Also, there is no need to check for even condition every time in the else part as the control jumps to else when if fails!.

n = int(input().strip())
if n % 2 != 0:
    print("Weird")
else:
    if n in range(2,6):
        print("Not Weird")

    elif n in range(6,21):
        print("Weird")

    elif n > 20:
        print("Not Weird")


问:
How can I disable gzip compression on requests going through APIM?
We have an Azure Api Management instance behind a Cloudflare firewall.
Recently we got a report of a client getting an error on a POST to the backend API.

It turned out issue was that the request was compressed (content-encoding gzip) and as the body partially contained base64 encoded stuff, the Cloudflare firewall identified that as a threat thus blocking it.

We have several options to address this, but the first option would be to see whether we can address this in APIM as different (mobile) clients sending in gzipped content will have this issue.

The most ideal solution would be to intercept some negotiation on compression, where we could just return false on that request. However I was unable to find such thing and I'm not sure about the impact on the clients.

Are there any other options we have in APIM to force clients not to send in gzip compressed requests?

答: Use set-header policy to set value of Content-Encoding header as appropriate. It will trigger internal logic in APIM to decompress/compress request content. Do that in inbound section to change request coming to backend, in outbound to change response to client.</p>


问:
Orchard Core CMS - Content Versioning, Scheduling and Audit Trail
We are considering Orchard Core CMS for our needs. There are three features that appear to have been supported in legacy Orchard - the ability to version content, schedule publishing and audit trails, but none of these appear to be available in Orchard Core CMS OOB.

How can functionality for the three features be accomplished in Orchard Core? Would they have to be done through the use of workflows or custom modules? Any insight into whether these features are on the roadmap?

Thanks!

答:
Received this response from Sebastian Ros, one of the key contributors to Orchard Core. As of the time of writing:

```<code>Content versioning is already implemented. There is no UI to list previous versions right now. There is an issue filed to track it.
Scheduled publishing can already be implemented using workflows, but there is an issue to track a more integrated solution, like in O1.
Audit trails is on the roadmap but not yet started.

1.0 will be shipped when all issues currently tagged with 1.0 and P0,P1,P2 flags have been implemented.
</code>```

https://github.com/OrchardCMS/OrchardCore/issues/5597

Body:
Received this response from Sebastian Ros, one of the key contributors to Orchard Core. As of the time of writing:

Content versioning is already implemented. There is no UI to list previous versions right now. There is an issue filed to track it.
Scheduled publishing can already be implemented using workflows, but there is an issue to track a more integrated solution, like in O1.
Audit trails is on the roadmap but not yet started.

1.0 will be shipped when all issues currently tagged with 1.0 and P0,P1,P2 flags have been implemented.

https://github.com/OrchardCMS/OrchardCore/issues/5597


问:
What would be consider as my local scope in this function?
just wondering what would be considered as my local scope in this function? Just a tad confused.</p>

```<code>function hello(name, age) {
    var message = name + ", who is " + age + " years old, says hi!";

    return function sayHello() {
        console.log(message);
    };
}

var sayHelloToJohn = hello("John", 33);

sayHelloToJohn();

</code>```

答:
Are you asking for the definition of the English word local? It just means "in the area". It's a relative term. The local scope is the scope of what you're currently talking about. When we speak of a variable local to a function, we mean that the variable isn't accessible outside said function.

When you declare a variable with var, it exists within the nearest enclosing function. When you declare a variable with let, it exists within the nearest enclosing braces { ... }.

In the example you've provided, 3 scopes were created:

The global scope which contains hello, sayHelloToJohn

hello's scope,  which contains name, age, message and sayHello

The scope of the sayHello function.

Body:
just wondering what would be considered as my local scope in this function? Just a tad confused.

function hello(name, age) {
    var message = name + ", who is " + age + " years old, says hi!";

    return function sayHello() {
        console.log(message);
    };
}

var sayHelloToJohn = hello("John", 33);

sayHelloToJohn();