问:
How to improve for-loop on DataFrame with row-wise calculation depending on previous row?
I have a working code with a for-loop that I would like to optimise in terms of speed (the project has been rejected because it's slow).

This is my situation: I have an Excel file from which I import a table with thousands of rows and a few columns into a Pandas DataFrame. The first column is a monotonic increasing series of timestamps, with 15 minutes frequency.

I have to use this table to calculate few extra columns, append them to the original table and save the resulting DataFrame into a new Excel file.

What is slowing the code is the core calculation of the extra columns. Here is a snippet of the working code:

```<code>import pandas as pd
from datetime import timedelta as td

cons_prod = pd.read_csv("sample.csv", index_col=0, parse_dates=True)

soc_dct = {}  # State of charge (kW)
charge_dct = {}  # Charge (kW)
discharge_dct = {}  # Discharge (kW)
acc_dct = {}  # Auto-consumption NEW (kW)
lst_dct = {}  # Lost injection due to battery efficiency (kW)
inj_dct = {}  # Injection NEW (kW)
gridcons_dct = {}  # Grid Consumption NEW (kW)
agg_dct = {}  # Additional Auto-consumption through battery (kW)

battery_parameters = {
    "power": 50,
    "energy": 130,
    "efficiency": 0.9,
    "minsoc": 0.1,
    "soct0": 65.0,
}

bp_energy = battery_parameters["energy"]
bp_power = battery_parameters["power"]
soct0 = 0.5 * bp_energy

for t in cons_prod.index:
    L = cons_prod.loc[t, "Injection (kW)"]
    m = cons_prod.loc[t, "Grid Consumption (kW)"]
    k = cons_prod.loc[t, "Auto-consumption (kW)"]
    f = cons_prod.loc[t, "Consumption (kW)"]
    if t == cons_prod.index[0]:
        # State of charge (kW)
        soc_dct.setdefault(t, soct0)

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t,
            (charge_dct[t] / battery_parameters["efficiency"]) - charge_dct[t],
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
    else:
        # State of charge (kW)
        soc_dct.setdefault(
            t,
            soc_dct[t - td(minutes=15)]
            + (charge_dct[t - td(minutes=15)] + discharge_dct[t - td(minutes=15)]) / 4,
        )

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t, charge_dct[t] / battery_parameters["efficiency"] - charge_dct[t]
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
# Creating a DataFrame with all the values
output_df = pd.DataFrame(
    data=[
        soc_dct,
        charge_dct,
        discharge_dct,
        acc_dct,
        lst_dct,
        inj_dct,
        gridcons_dct,
        agg_dct,
    ]
).T
output_df.columns = [
    "State of charge (kW)",
    "Charge (kW)",
    "Discharge (kW)",
    "Auto-consumption NEW (kW)",
    "Lost injection due to battery efficiency (kW)",
    "Injection NEW (kW)",
    "Grid Consumption NEW (kW)",
    "Additional Auto-consumption through battery (kW)",
]
charge_dct = {}  # Charge (kW)
discharge_dct = {}  # Discharge (kW)
acc_dct = {}  # Auto-consumption NEW (kW)
lst_dct = {}  # Lost injection due to battery efficiency (kW)
inj_dct = {}  # Injection NEW (kW)
gridcons_dct = {}  # Grid Consumption NEW (kW)
agg_dct = {}  # Additional Auto-consumption through battery (kW)

for t in cons_prod.index:
    L = cons_prod.loc[t, "Injection (kW)"]
    m = cons_prod.loc[t, "Grid Consumption (kW)"]
    k = cons_prod.loc[t, "Auto-consumption (kW)"]
    f = cons_prod.loc[t, "Consumption (kW)"]
    if t == cons_prod.index[0]:
        # State of charge (kW)
        soc_dct.setdefault(t, soct0)

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t,
            (charge_dct[t] / battery_parameters["efficiency"]) - charge_dct[t],
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
    else:
        # State of charge (kW)
        soc_dct.setdefault(
            t,
            soc_dct[t - td(minutes=15)]
            + (charge_dct[t - td(minutes=15)] + discharge_dct[t - td(minutes=15)]) / 4,
        )

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t, charge_dct[t] / battery_parameters["efficiency"] - charge_dct[t]
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
# Creating a DataFrame with all the values
output_df = pd.DataFrame(
    data=[
        soc_dct,
        charge_dct,
        discharge_dct,
        acc_dct,
        lst_dct,
        inj_dct,
        gridcons_dct,
        agg_dct,
    ]
).T
output_df.columns = [
    "State of charge (kW)",
    "Charge (kW)",
    "Discharge (kW)",
    "Auto-consumption NEW (kW)",
    "Lost injection due to battery efficiency (kW)",
    "Injection NEW (kW)",
    "Grid Consumption NEW (kW)",
    "Additional Auto-consumption through battery (kW)",
]

</code>```

cons_prod is the table imported into a DataFrame.

As you can see, we have two situations: when t == cons_prod.index[0] (i.e., the first item of the timestamps), the calculations use the values at the same t. However, from the second timestamp on, some of the calculations refer to the previous value (in here referred to the 15 minutes before using the index t - td(minutes=15)).

These are the reasons why I am struggling to move away from the for-loop.

A few explanations to possible questions

Q: Why are you using dictionaries? A: Because I figured that they fill faster than other data types, and I can use them to create a DataFrame later on.

Q: Are the timestamps coherent, e.g. do they have missing values? A: No missing values, as there is a previous function I wrote to make sure that the timestamps are filled completely.

Q: The calculations do not currently refer to a previous row in a DataFrame, but in a dictionary! Why the misleading title? A: This is the best solution I could come up with so far, but I am wondering whether my not-so-complete knowledge of Pandas is hiding a simpler, faster solution.

Hope the framework is clear.

Thank you in advance!

EDIT: as per request, added a 100-lines sample of cons_prod and modified the previous code to meet the requirements of a MRE.

EDIT 2: I have tried moving from dictionaries to a Pandas lookup, trying to optimise as much as possible. This is the code I came up with:

```<code>from time import time as tt

cp = cons_prod.copy(deep=True)

# Initialise the columns filling them with zeroes
cp["State of charge (kW)"] = 0
cp["Charge (kW)"] = 0
cp["Discharge (kW)"] = 0

# Storing the position of the columns in variables
cp_soc = cp.columns.get_loc("State of charge (kW)")
cp_charge = cp.columns.get_loc("Charge (kW)")
cp_discharge = cp.columns.get_loc("Discharge (kW)")
cp_inj = cp.columns.get_loc("Injection (kW)")
cp_gridcons = cp.columns.get_loc("Grid Consumption (kW)")

# Storing the values of the battery dictionary lookups in variables
bp_energy = dct_bp["energy"]
bp_power = dct_bp["power"]
bp_efficiency = dct_bp["efficiency"]
bp_soct0 = dct_bp["soct0"]
bp_minsoc = dct_bp["minsoc"]

start1 = tt()  # Measuring time
for row in cp.itertuples(name=None):  # Using itertuples to gain some speed
    L = cp.loc[row[0], "Injection (kW)"]
    m = cp.loc[row[0], "Grid Consumption (kW)"]
    k = cp.loc[row[0], "Auto-consumption (kW)"]
    f = cp.loc[row[0], "Consumption (kW)"]
    if row[0] == cp.index[0]:
        cp.iloc[0, cp_soc] = bp_soct0
        cp.iloc[0, cp_charge] = float(
            min(L, (bp_energy - bp_soct0) * 4, bp_power) * bp_efficiency
            if L >= 0
            else 0,
        )
        cp.iloc[0, cp_discharge] = float(
            -min(
                m,
                4 * bp_soct0 - 4 * (bp_minsoc * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0
        )
    else:
        t = pd.Index(cp.index).get_loc(row[0])
        cp.iloc[t, cp_soc] = float(
            cp.iloc[t - 1, cp_soc]
            + (cp.iloc[t - 1, cp_charge] + cp.iloc[t - 1, cp_discharge]) / 4
        )
        cp.iloc[t, cp_charge] = float(
            min(L, (bp_energy - cp.iloc[t, cp_soc]) * 4, bp_power) * bp_efficiency
            if L >= 0
            else 0,
        )
        cp.iloc[t, cp_discharge] = float(
            -min(
                m,
                4 * cp.iloc[t, cp_soc] - 4 * (dct_bp["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0
        )
end1 = tt() - start1
print(f"Pandas lookup took {end1:.2f} seconds")

</code>```

With this code, I got an average of 42 seconds per complete task, while I used to have <20 seconds with dictionaries.

答:
The accessing dict is fast in Python perspective, however, not quite true for Pandas perspective. One of the best feature of Pandas is the vectorization which makes the Pandas performs quite efficient on the large dataset.

What is vectorization, why is fast? => What is "vectorization"?

Also, I want to leave this reference. When you are working on the Pandas, try looking for the operations in the order that is mentioned in the link to optimize the processes.

https://stackoverflow.com/a/55557758/2956135

Back to your case, your calculations of most of parameters are only depending onto the data from the same row. This is the perfect case that you can do vectorization easily.

The 3 parameters ("State of charge", "Charge", and "Discharge", are depending onto each other and depending onto the calculation result from the previous row.  This part I am not finding a way to vectorize. Hopefully, someone can optimize this further.

First I take out constant dictionary and keep it as basic constant. This is probably not making much difference but having simple reference is better than having an additional step to access constant in dictionary. If you had to pass multiple constants to a function, putting into dictionary and passing it as dictionary makes sense but here it is not the case.

power = 50
efficiency = 0.9
minsoc = 0.1
soct0 = 65.0
bp_energy = 130
bp_power = 50
soct0 = 0.5 * bp_energy
```
<p>Then, define the function to calculate the 3 params, take out any calculations of other params.</p>
<pre class="lang-py prettyprint-override"><code>def _calc_soc_discharge(prev, L, m):
    if prev is None:
        soc = 65.0

        # Charge (kW)
        charge = min(
            L,
            (bp_energy - soc) * 4,
            bp_power,
        ) * efficiency if L >= 0 else 0

        # Discharge (kW)
        discharge =  -min(
            m,
            4 * soc - 4 * (minsoc * bp_energy),
            bp_power,
        ) if m >= 0 else 0
        return [soc, charge, discharge]
    else:
        soc = prev[0] + (prev[1] + prev[2]) / 4

        # Charge (kW)
        charge = min(
            L,
            (bp_energy - soc) * 4,
            bp_power,
        ) * efficiency if L >= 0 else 0

        # Discharge (kW)
        discharge = -min(
            m,
            4 * soc - 4 * (minsoc * bp_energy),
            bp_power,
        ) if m >= 0 else 0

        return [soc, charge, discharge]
</code>```

Call this function iteratively and append the result back to the dataframe.

scd = []
for i, row in cons_prod[['Injection (kW)', 'Grid Consumption (kW)']].iterrows():
    scd.append(_calc_soc_discharge(None if len(scd) == 0 else scd[-1], row['Injection (kW)'], row['Grid Consumption (kW)']))

cons_prod = pd.concat([cons_prod, pd.DataFrame(scd, columns=["State of charge (kW)", "Charge (kW)", "Discharge (kW)"], index=cons_prod.index)], axis=1)
```
<p>Now, this dataframe has all data required to calculate other parameters. Here we use vectorization. This part should be really optimized. The mathematical operations calling with the Pandas Series is part of the vectorization.</p>
```cons_prod['Auto-consumption NEW (kW)'] = cons_prod['Auto-consumption (kW)'] - cons_prod['Discharge (kW)']
cons_prod['Lost injection due to battery efficiency (kW)'] = cons_prod['Charge (kW)'] / efficiency - cons_prod['Charge (kW)']
cons_prod['Injection NEW (kW)'] = cons_prod['Injection (kW)'] - cons_prod['Charge (kW)'] - cons_prod['Lost injection due to battery efficiency (kW)']
cons_prod['Grid Consumption NEW (kW)'] = cons_prod['Consumption (kW)'] - cons_prod['Auto-consumption NEW (kW)']
cons_prod['Additional Auto-consumption through battery (kW)'] = cons_prod['Auto-consumption NEW (kW)'] - cons_prod['Auto-consumption (kW)']
```
<p>Benchmark</p>
<p>With the sample data on my laptop.</p>
<pre class="lang-none prettyprint-override"><code>Original solution: 48.2 ms ± 6.17 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
With vectorization: 13.8 ms ± 2.13 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
</code>```

Body:
I have a working code with a for-loop that I would like to optimise in terms of speed (the project has been rejected because it's slow).

This is my situation: I have an Excel file from which I import a table with thousands of rows and a few columns into a Pandas DataFrame. The first column is a monotonic increasing series of timestamps, with 15 minutes frequency.

I have to use this table to calculate few extra columns, append them to the original table and save the resulting DataFrame into a new Excel file.

What is slowing the code is the core calculation of the extra columns. Here is a snippet of the working code:

import pandas as pd
from datetime import timedelta as td

cons_prod = pd.read_csv("sample.csv", index_col=0, parse_dates=True)

soc_dct = {}  # State of charge (kW)
charge_dct = {}  # Charge (kW)
discharge_dct = {}  # Discharge (kW)
acc_dct = {}  # Auto-consumption NEW (kW)
lst_dct = {}  # Lost injection due to battery efficiency (kW)
inj_dct = {}  # Injection NEW (kW)
gridcons_dct = {}  # Grid Consumption NEW (kW)
agg_dct = {}  # Additional Auto-consumption through battery (kW)

battery_parameters = {
    "power": 50,
    "energy": 130,
    "efficiency": 0.9,
    "minsoc": 0.1,
    "soct0": 65.0,
}

bp_energy = battery_parameters["energy"]
bp_power = battery_parameters["power"]
soct0 = 0.5 * bp_energy

for t in cons_prod.index:
    L = cons_prod.loc[t, "Injection (kW)"]
    m = cons_prod.loc[t, "Grid Consumption (kW)"]
    k = cons_prod.loc[t, "Auto-consumption (kW)"]
    f = cons_prod.loc[t, "Consumption (kW)"]
    if t == cons_prod.index[0]:
        # State of charge (kW)
        soc_dct.setdefault(t, soct0)

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t,
            (charge_dct[t] / battery_parameters["efficiency"]) - charge_dct[t],
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
    else:
        # State of charge (kW)
        soc_dct.setdefault(
            t,
            soc_dct[t - td(minutes=15)]
            + (charge_dct[t - td(minutes=15)] + discharge_dct[t - td(minutes=15)]) / 4,
        )

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t, charge_dct[t] / battery_parameters["efficiency"] - charge_dct[t]
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
# Creating a DataFrame with all the values
output_df = pd.DataFrame(
    data=[
        soc_dct,
        charge_dct,
        discharge_dct,
        acc_dct,
        lst_dct,
        inj_dct,
        gridcons_dct,
        agg_dct,
    ]
).T
output_df.columns = [
    "State of charge (kW)",
    "Charge (kW)",
    "Discharge (kW)",
    "Auto-consumption NEW (kW)",
    "Lost injection due to battery efficiency (kW)",
    "Injection NEW (kW)",
    "Grid Consumption NEW (kW)",
    "Additional Auto-consumption through battery (kW)",
]
charge_dct = {}  # Charge (kW)
discharge_dct = {}  # Discharge (kW)
acc_dct = {}  # Auto-consumption NEW (kW)
lst_dct = {}  # Lost injection due to battery efficiency (kW)
inj_dct = {}  # Injection NEW (kW)
gridcons_dct = {}  # Grid Consumption NEW (kW)
agg_dct = {}  # Additional Auto-consumption through battery (kW)

for t in cons_prod.index:
    L = cons_prod.loc[t, "Injection (kW)"]
    m = cons_prod.loc[t, "Grid Consumption (kW)"]
    k = cons_prod.loc[t, "Auto-consumption (kW)"]
    f = cons_prod.loc[t, "Consumption (kW)"]
    if t == cons_prod.index[0]:
        # State of charge (kW)
        soc_dct.setdefault(t, soct0)

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t,
            (charge_dct[t] / battery_parameters["efficiency"]) - charge_dct[t],
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
    else:
        # State of charge (kW)
        soc_dct.setdefault(
            t,
            soc_dct[t - td(minutes=15)]
            + (charge_dct[t - td(minutes=15)] + discharge_dct[t - td(minutes=15)]) / 4,
        )

        # Charge (kW)
        charge_dct.setdefault(
            t,
            min(
                L,
                (bp_energy - soc_dct[t]) * 4,
                bp_power,
            )
            * battery_parameters["efficiency"]
            if L >= 0
            else 0,
        )

        # Discharge (kW)
        discharge_dct.setdefault(
            t,
            -min(
                m,
                4 * soc_dct[t] - 4 * (battery_parameters["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0,
        )

        # Auto-consumption NEW (kW)
        acc_dct.setdefault(t, k - discharge_dct[t])

        # Lost injection due to battery efficiency (kW)
        lst_dct.setdefault(
            t, charge_dct[t] / battery_parameters["efficiency"] - charge_dct[t]
        )

        # Injection NEW (kW)
        inj_dct.setdefault(t, L - charge_dct[t] - lst_dct[t])

        # Grid Consumption NEW (kW)
        gridcons_dct.setdefault(t, f - acc_dct[t])

        # Additional Auto-consumption through battery (kW)
        agg_dct.setdefault(t, acc_dct[t] - k)
# Creating a DataFrame with all the values
output_df = pd.DataFrame(
    data=[
        soc_dct,
        charge_dct,
        discharge_dct,
        acc_dct,
        lst_dct,
        inj_dct,
        gridcons_dct,
        agg_dct,
    ]
).T
output_df.columns = [
    "State of charge (kW)",
    "Charge (kW)",
    "Discharge (kW)",
    "Auto-consumption NEW (kW)",
    "Lost injection due to battery efficiency (kW)",
    "Injection NEW (kW)",
    "Grid Consumption NEW (kW)",
    "Additional Auto-consumption through battery (kW)",
]

cons_prod is the table imported into a DataFrame.

As you can see, we have two situations: when t == cons_prod.index[0] (i.e., the first item of the timestamps), the calculations use the values at the same t. However, from the second timestamp on, some of the calculations refer to the previous value (in here referred to the 15 minutes before using the index t - td(minutes=15)).

These are the reasons why I am struggling to move away from the for-loop.

A few explanations to possible questions

Q: Why are you using dictionaries? A: Because I figured that they fill faster than other data types, and I can use them to create a DataFrame later on.

Q: Are the timestamps coherent, e.g. do they have missing values? A: No missing values, as there is a previous function I wrote to make sure that the timestamps are filled completely.

Q: The calculations do not currently refer to a previous row in a DataFrame, but in a dictionary! Why the misleading title? A: This is the best solution I could come up with so far, but I am wondering whether my not-so-complete knowledge of Pandas is hiding a simpler, faster solution.

Hope the framework is clear.

Thank you in advance!

EDIT: as per request, added a 100-lines sample of cons_prod and modified the previous code to meet the requirements of a MRE.

EDIT 2: I have tried moving from dictionaries to a Pandas lookup, trying to optimise as much as possible. This is the code I came up with:

from time import time as tt

cp = cons_prod.copy(deep=True)

# Initialise the columns filling them with zeroes
cp["State of charge (kW)"] = 0
cp["Charge (kW)"] = 0
cp["Discharge (kW)"] = 0

# Storing the position of the columns in variables
cp_soc = cp.columns.get_loc("State of charge (kW)")
cp_charge = cp.columns.get_loc("Charge (kW)")
cp_discharge = cp.columns.get_loc("Discharge (kW)")
cp_inj = cp.columns.get_loc("Injection (kW)")
cp_gridcons = cp.columns.get_loc("Grid Consumption (kW)")

# Storing the values of the battery dictionary lookups in variables
bp_energy = dct_bp["energy"]
bp_power = dct_bp["power"]
bp_efficiency = dct_bp["efficiency"]
bp_soct0 = dct_bp["soct0"]
bp_minsoc = dct_bp["minsoc"]

start1 = tt()  # Measuring time
for row in cp.itertuples(name=None):  # Using itertuples to gain some speed
    L = cp.loc[row[0], "Injection (kW)"]
    m = cp.loc[row[0], "Grid Consumption (kW)"]
    k = cp.loc[row[0], "Auto-consumption (kW)"]
    f = cp.loc[row[0], "Consumption (kW)"]
    if row[0] == cp.index[0]:
        cp.iloc[0, cp_soc] = bp_soct0
        cp.iloc[0, cp_charge] = float(
            min(L, (bp_energy - bp_soct0) * 4, bp_power) * bp_efficiency
            if L >= 0
            else 0,
        )
        cp.iloc[0, cp_discharge] = float(
            -min(
                m,
                4 * bp_soct0 - 4 * (bp_minsoc * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0
        )
    else:
        t = pd.Index(cp.index).get_loc(row[0])
        cp.iloc[t, cp_soc] = float(
            cp.iloc[t - 1, cp_soc]
            + (cp.iloc[t - 1, cp_charge] + cp.iloc[t - 1, cp_discharge]) / 4
        )
        cp.iloc[t, cp_charge] = float(
            min(L, (bp_energy - cp.iloc[t, cp_soc]) * 4, bp_power) * bp_efficiency
            if L >= 0
            else 0,
        )
        cp.iloc[t, cp_discharge] = float(
            -min(
                m,
                4 * cp.iloc[t, cp_soc] - 4 * (dct_bp["minsoc"] * bp_energy),
                bp_power,
            )
            if m >= 0
            else 0
        )
end1 = tt() - start1
print(f"Pandas lookup took {end1:.2f} seconds")

With this code, I got an average of 42 seconds per complete task, while I used to have <20 seconds with dictionaries.

Body:
The accessing dict is fast in Python perspective, however, not quite true for Pandas perspective. One of the best feature of Pandas is the vectorization which makes the Pandas performs quite efficient on the large dataset.

What is vectorization, why is fast? => What is "vectorization"?

Also, I want to leave this reference. When you are working on the Pandas, try looking for the operations in the order that is mentioned in the link to optimize the processes.

https://stackoverflow.com/a/55557758/2956135

Back to your case, your calculations of most of parameters are only depending onto the data from the same row. This is the perfect case that you can do vectorization easily.

The 3 parameters ("State of charge", "Charge", and "Discharge", are depending onto each other and depending onto the calculation result from the previous row.  This part I am not finding a way to vectorize. Hopefully, someone can optimize this further.

First I take out constant dictionary and keep it as basic constant. This is probably not making much difference but having simple reference is better than having an additional step to access constant in dictionary. If you had to pass multiple constants to a function, putting into dictionary and passing it as dictionary makes sense but here it is not the case.

power = 50
efficiency = 0.9
minsoc = 0.1
soct0 = 65.0
bp_energy = 130
bp_power = 50
soct0 = 0.5 * bp_energy

Then, define the function to calculate the 3 params, take out any calculations of other params.

def _calc_soc_discharge(prev, L, m):
    if prev is None:
        soc = 65.0

        # Charge (kW)
        charge = min(
            L,
            (bp_energy - soc) * 4,
            bp_power,
        ) * efficiency if L >= 0 else 0

        # Discharge (kW)
        discharge =  -min(
            m,
            4 * soc - 4 * (minsoc * bp_energy),
            bp_power,
        ) if m >= 0 else 0
        return [soc, charge, discharge]
    else:
        soc = prev[0] + (prev[1] + prev[2]) / 4

        # Charge (kW)
        charge = min(
            L,
            (bp_energy - soc) * 4,
            bp_power,
        ) * efficiency if L >= 0 else 0

        # Discharge (kW)
        discharge = -min(
            m,
            4 * soc - 4 * (minsoc * bp_energy),
            bp_power,
        ) if m >= 0 else 0

        return [soc, charge, discharge]

Call this function iteratively and append the result back to the dataframe.

scd = []
for i, row in cons_prod[['Injection (kW)', 'Grid Consumption (kW)']].iterrows():
    scd.append(_calc_soc_discharge(None if len(scd) == 0 else scd[-1], row['Injection (kW)'], row['Grid Consumption (kW)']))

cons_prod = pd.concat([cons_prod, pd.DataFrame(scd, columns=["State of charge (kW)", "Charge (kW)", "Discharge (kW)"], index=cons_prod.index)], axis=1)

Now, this dataframe has all data required to calculate other parameters. Here we use vectorization. This part should be really optimized. The mathematical operations calling with the Pandas Series is part of the vectorization.

cons_prod['Auto-consumption NEW (kW)'] = cons_prod['Auto-consumption (kW)'] - cons_prod['Discharge (kW)']
cons_prod['Lost injection due to battery efficiency (kW)'] = cons_prod['Charge (kW)'] / efficiency - cons_prod['Charge (kW)']
cons_prod['Injection NEW (kW)'] = cons_prod['Injection (kW)'] - cons_prod['Charge (kW)'] - cons_prod['Lost injection due to battery efficiency (kW)']
cons_prod['Grid Consumption NEW (kW)'] = cons_prod['Consumption (kW)'] - cons_prod['Auto-consumption NEW (kW)']
cons_prod['Additional Auto-consumption through battery (kW)'] = cons_prod['Auto-consumption NEW (kW)'] - cons_prod['Auto-consumption (kW)']

Benchmark

With the sample data on my laptop.

Original solution: 48.2 ms ± 6.17 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
With vectorization: 13.8 ms ± 2.13 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)


来源: stackexchange

问:
Unable to resolve System.Windows.Forms.dll in .Net Core 3.1
I have a scenario where we are using a legacy .Net Framework dll in .Net core 3.1 class library. Internally .Net Framework dll is using System.Windows.Forms.dll which .Net core is not able to resolve.

I am getting below error message during runtime

Could not load file or assembly 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. The system cannot find the file specified.

In a ideal world there is no point in adding System.Windows.Forms.dll to a class library but is there any way to add System.Windows.Forms and its dependencies in .Net core class library.

Note: I have tried manually adding System.Windows.Forms.dll but it did not work out.

答:
It works with me in .net core 3.1 by adding <UseWindowsForms>True</UseWindowsForms> inside project .csproj file to become like this:

```<code><PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWindowsForms>True</UseWindowsForms>
</PropertyGroup>
</code>```

ContentLicense: CC BY-SA 4.0

Body:
It works with me in .net core 3.1 by adding <UseWindowsForms>True</UseWindowsForms> inside project .csproj file to become like this:

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <UseWindowsForms>True</UseWindowsForms>
</PropertyGroup>


问:
Bootstrap card columns masonry effect - change height cards are jumpy
I use the bootstrap card columns masonry. If the use clicks on a button (inside the card) the height of the card is changed (I dynamically add the card-footer).

The problem is, in special constellations the cards change the position and it looks kinda "jumpy".

I set up this jsfiddle. Just click on the firsts card select button and you will see the card among them will jump to the right.
(Maybe change the window size until you have 4 cards next to each other)

https://jsfiddle.net/rvt8a690/2/

EDIT: Maybe you have to play a bit with the screen size if you can't recreate the bug. But I made this little gif where you can see the bug:

$('.ccs-product-counter').on('click', function(e) {

  let selectedProductID = $(this).find('span.badge').attr("data-product-id");

  if (!$('#undo-p-id-' + selectedProductID).hasClass("UndoIsVisible")) {
    $('#undo-p-id-' + selectedProductID).removeClass('d-none');
    $('#undo-p-id-' + selectedProductID).addClass('fadeInDown');
    $('#undo-p-id-' + selectedProductID).addClass('UndoIsVisible');
    $('#card-p-id-' + selectedProductID).addClass('animationIsRunning');
    setTimeout(function() {
      $('#undo-p-id-' + selectedProductID).removeClass('fadeInDown');
      $('#card-p-id-' + selectedProductID).removeClass('animationIsRunning');
    }, 800);
  }

});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>@media (min-width: 34em) {
  .card-columns {
    -webkit-column-count: 2;
    -moz-column-count: 2;
    column-count: 2;
  }
}

@media (min-width: 48em) {
  .card-columns {
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
  }
}

@media (min-width: 62em) {
  .card-columns {
    -webkit-column-count: 4;
    -moz-column-count: 4;
    column-count: 4;
  }
}

@media (min-width: 75em) {
  .card-columns {
    -webkit-column-count: 4;
    -moz-column-count: 4;
    column-count: 4;
  }
}</code>```

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>

Title

                    Subtitle

          Lorem ipsum dolor sit amet

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Descrconsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Descr. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eiption

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Lorem ipsum consetetur sadipscing elitr, sed diam nonumy e

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

```

答:
I've had this issue for several days now. I kept having to change the way things are displayed or pop up. I believe that I have found the solution to this issue.

In the card-columns style, there's an attribute called orphans and the value is 1. I overwrite it to orphans: unset;

This way, the cards will not try to rearrange themselves when the height of the card changes.

ug9mLytojsFiddle

Body:
I use the bootstrap card columns masonry. If the use clicks on a button (inside the card) the height of the card is changed (I dynamically add the card-footer).

The problem is, in special constellations the cards change the position and it looks kinda "jumpy".

I set up this jsfiddle. Just click on the firsts card select button and you will see the card among them will jump to the right.
(Maybe change the window size until you have 4 cards next to each other)

https://jsfiddle.net/rvt8a690/2/

EDIT: Maybe you have to play a bit with the screen size if you can't recreate the bug. But I made this little gif where you can see the bug:

$('.ccs-product-counter').on('click', function(e) {

  let selectedProductID = $(this).find('span.badge').attr("data-product-id");

  if (!$('#undo-p-id-' + selectedProductID).hasClass("UndoIsVisible")) {
    $('#undo-p-id-' + selectedProductID).removeClass('d-none');
    $('#undo-p-id-' + selectedProductID).addClass('fadeInDown');
    $('#undo-p-id-' + selectedProductID).addClass('UndoIsVisible');
    $('#card-p-id-' + selectedProductID).addClass('animationIsRunning');
    setTimeout(function() {
      $('#undo-p-id-' + selectedProductID).removeClass('fadeInDown');
      $('#card-p-id-' + selectedProductID).removeClass('animationIsRunning');
    }, 800);
  }

});

@media (min-width: 34em) {
  .card-columns {
    -webkit-column-count: 2;
    -moz-column-count: 2;
    column-count: 2;
  }
}

@media (min-width: 48em) {
  .card-columns {
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
  }
}

@media (min-width: 62em) {
  .card-columns {
    -webkit-column-count: 4;
    -moz-column-count: 4;
    column-count: 4;
  }
}

@media (min-width: 75em) {
  .card-columns {
    -webkit-column-count: 4;
    -moz-column-count: 4;
    column-count: 4;
  }
}

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>

Title

                    Subtitle

          Lorem ipsum dolor sit amet

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Descrconsetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Descr. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eiption

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          Lorem ipsum consetetur sadipscing elitr, sed diam nonumy e

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection

Title

                      Subtitle

          voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit

          Price: 2$

          Stock: 5

        <button type="button" class="btn btn-primary d-block center-margin-0-auto ccs-product-counter">Select 0
              </button>

           Undo selection


问:
Add key:value to dictionary if variable is not None
I have a function clans(), that accepts 8 arguments. I need to add key and value pair to dictionary if argument is not None. There is my solution:

```<code>def clans(self, name: str = None, warFrequency: str = None, location: str = None,
            minMembers: int = None, maxMembers: int = None,
            minClanPoints: int = None, minClanLevel: int = None,
            labels: list[str] = None):
    params = {} # <- the dictionary to add to

    # very much if-conditions
    if name is not None:
        params['name'] = name
    if warFrequency is not None:
        params['warFrequency'] = warFrequency
    ... # <- other function arguments and if conditions
    if labels is not None:
        params['labels'] = labels

    return params
</code>```

I think it is not the most optimal solution due to the large amount of code and poor readability, how can I improve that code? I have an idea like (but I dont know how to realize it):

```<code>params = {}
for arg in args: # <- args is list of function arguments
    if arg is not None:
        params[arg.key()] = arg.value() # <- arg.key() is argument name, arg.value() is value
</code>```

答:
You might reconsider your strategy.

It's better to have a dictionary with a value of None for certain keys than an inconsistent dictionary where some keys might not exist.

So if you allow the function clans to be called with some missing info, just create that key and assign a value of none. That's perfectly fine since maybe you don't have that info at this point.

Later on you can have a function that updates those values, so you just reassign a dictionary key which already exist and you don't have to worry about those keys not existing.

So, I would do something like:

```<code>def clans(self, name: str = None, warFrequency: str = None, location: str = None,
            minMembers: int = None, maxMembers: int = None,
            minClanPoints: int = None, minClanLevel: int = None,
            labels: list[str] = None):
    myKeys = ["name", "warFrequency", "location", "minMembers", "maxMembers", "minClanPoints", "minClanLevel"]
    myValues = [name, warFrequency, location, minMembers, maxMembers, minClanPoints, minClanLevel]
    return dict(zip(myKeys, myValues))
</code>```

This way you have a consistent dictionary. You will have to check later if some values are None.

Creating a dictionary with missing keys will force you to check if they exist in a future, instead not you can just check if they are None

So instead of doing

if "location" in myDict.Keys():

You just do

if myDict["location"] is not None:

Body:
I have a function clans(), that accepts 8 arguments. I need to add key and value pair to dictionary if argument is not None. There is my solution:

def clans(self, name: str = None, warFrequency: str = None, location: str = None,
            minMembers: int = None, maxMembers: int = None,
            minClanPoints: int = None, minClanLevel: int = None,
            labels: list[str] = None):
    params = {} # <- the dictionary to add to

    # very much if-conditions
    if name is not None:
        params['name'] = name
    if warFrequency is not None:
        params['warFrequency'] = warFrequency
    ... # <- other function arguments and if conditions
    if labels is not None:
        params['labels'] = labels

    return params

I think it is not the most optimal solution due to the large amount of code and poor readability, how can I improve that code? I have an idea like (but I dont know how to realize it):

params = {}
for arg in args: # <- args is list of function arguments
    if arg is not None:
        params[arg.key()] = arg.value() # <- arg.key() is argument name, arg.value() is value

Body:
You might reconsider your strategy.

It's better to have a dictionary with a value of None for certain keys than an inconsistent dictionary where some keys might not exist.

So if you allow the function clans to be called with some missing info, just create that key and assign a value of none. That's perfectly fine since maybe you don't have that info at this point.

Later on you can have a function that updates those values, so you just reassign a dictionary key which already exist and you don't have to worry about those keys not existing.

So, I would do something like:

def clans(self, name: str = None, warFrequency: str = None, location: str = None,
            minMembers: int = None, maxMembers: int = None,
            minClanPoints: int = None, minClanLevel: int = None,
            labels: list[str] = None):
    myKeys = ["name", "warFrequency", "location", "minMembers", "maxMembers", "minClanPoints", "minClanLevel"]
    myValues = [name, warFrequency, location, minMembers, maxMembers, minClanPoints, minClanLevel]
    return dict(zip(myKeys, myValues))

This way you have a consistent dictionary. You will have to check later if some values are None.

Creating a dictionary with missing keys will force you to check if they exist in a future, instead not you can just check if they are None

So instead of doing

if "location" in myDict.Keys():

You just do

if myDict["location"] is not None:


问:
How to hide a DIV element using RegEx and Jquery
I would like to hide all other element except class="imagebrowser" in following,

```<code><div class="entry">
    <p>Heading 1</p>
    <p>Heading 2</p>
        ...
    <p>Heading n</p>
    <b>This is abold text</b>
    <div>This is a div element</div>

    <div class="imagebrowser">
        Hello world
    </div>
</div>
</code>```

Expected result,

```<code><div class="entry">

    <div class="imagebrowser">
        Hello world
    </div>
</div>
</code>```

Any help please

答:
```<code>$('div.entry div').not('.imagebrowser').hide();
</code>```

This will hide all divs inside the "entry" div other than those with the class "imagebrowser".

ContentLicense: CC BY-SA 3.0

Body:
I would like to hide all other element except class="imagebrowser" in following,

Heading 1

Heading 2

        ...

Heading n

    This is abold text

This is a div element

        Hello world

Expected result,

        Hello world

Any help please

Body:
$('div.entry div').not('.imagebrowser').hide();

This will hide all divs inside the "entry" div other than those with the class "imagebrowser".


问:
How can I put multiple elements into ‘elem’
Let’s say I want to do something like"ace" `elem` "abcdefg". Of course we can’t because you need a list of the first elements type. Instead is there a way we could turn this into taking every char in "ace" and comparing them individually with "abcdefg", then using or statements to combine them, but without manually doing this (because in my program it’s a variable of unknown length and characters).

答:
Here's using that or statement as you wanted:

```<code>or [c `elem` "abcdefg" | c <- "ace"]
</code>```

How to come up with this?

You already know that you want

```<code>  'a' `elem` "abcdefg" ||
  'c' `elem` "abcdefg" ||
  'e' `elem` "abcdefg"
</code>```

and the type of (||) is Bool -> Bool -> Bool.

But you have a list of the characters to test. And after you've tested each of them, you'll have the list of Boolean results. Thus you want a function of type [Bool] -> Bool.

Hoogle time!

Body:
Here's using that or statement as you wanted:

or [c `elem` "abcdefg" | c <- "ace"]

How to come up with this?

You already know that you want

  'a' `elem` "abcdefg" ||
  'c' `elem` "abcdefg" ||
  'e' `elem` "abcdefg"

and the type of (||) is Bool -> Bool -> Bool.

But you have a list of the characters to test. And after you've tested each of them, you'll have the list of Boolean results. Thus you want a function of type [Bool] -> Bool.

Hoogle time!


问:
MySql: Select value of current and next row
I am trying to learn of a better way in achieving the desired result of a select query - details below, thank you in advance.

MySQL version: 5.7

Table:
id int(11)
product_number int(8)
service_group int (4)
datetime datetime
value int (6)

Indexes on all but value column.

MySql table has the following data:

```<code>id,product_number, service_group,datetime,value
1,1234,1,2022-02-10 00:00:00,0
2,1234,1,2022-02-10 00:01:30,25
3,1234,1,2022-02-10 00:02:30,11
4,1234,2,2022-02-10 01:00:30,0
5,1234,2,2022-02-10 01:01:30,65
6,1234,2,2022-02-10 01:02:30,55
</code>```

In essence, the value for each product within the service group is wrongly recorded, and the correct value for the "current" row is actually recorded against the next row for the product within the same service group - correct output should look like this:

```<code>id,product_number, service_group,datetime,value
1,1234,1,2022-02-10 00:00:00,25
2,1234,1,2022-02-10 00:01:30,11
3,1234,1,2022-02-10 00:02:30,0
4,1234,2,2022-02-10 01:00:30,65
5,1234,2,2022-02-10 01:01:30,55
6,1234,2,2022-02-10 01:02:30,0
</code>```

The below query is what seems to be hugely inefficient way of returning the correct results - what would be a better way to go about this in MySql? Thank you.

```<code>Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (
    Select b.value FROM products b
    Where b.product_number=a.product_number AND b.service_group=a.service_group
    AND b.datetime>a.datetime
    Order by b.datetime ASC
    Limit 1
    )
FROM products a```
```

答:
If there's no skipped id (the number is in sequence) then you could probably use simple select like below

1.

```<code>Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (Select b.value FROM products b Where b.id = a.id+1)
FROM products a
</code>```

```<code>Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    b.value
FROM products a
INNER JOIN products b ON b.id = a.id+1
</code>```

Note that both SQL 1 and 2 is assuming your ID is primary key as I see that's an incrementing value

Either way you need to run an explain query so you could analyze which one is the most efficient one

And more importantly I suggest to update it if it's "wrongly recorded", you should put the your service on maintenance mode and do update+fix on the data using query

Edit:
based on your comment "Hi, Gunawan. Thank you for your suggestion. Unfortunately IDs will not be in sequences to support the proposed approach."

You could alter the subquery on (1) a bit to

```<code>Select b.value
FROM products b
Where b.id > a.id order by id asc limit 1
</code>```

so it became

```<code>Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (Select b.value FROM products b Where b.id > a.id order by b.id asc limit 1)
FROM products a
</code>```

Body:
I am trying to learn of a better way in achieving the desired result of a select query - details below, thank you in advance.

MySQL version: 5.7

Table:
id int(11)
product_number int(8)
service_group int (4)
datetime datetime
value int (6)

Indexes on all but value column.

MySql table has the following data:

id,product_number, service_group,datetime,value
1,1234,1,2022-02-10 00:00:00,0
2,1234,1,2022-02-10 00:01:30,25
3,1234,1,2022-02-10 00:02:30,11
4,1234,2,2022-02-10 01:00:30,0
5,1234,2,2022-02-10 01:01:30,65
6,1234,2,2022-02-10 01:02:30,55

In essence, the value for each product within the service group is wrongly recorded, and the correct value for the "current" row is actually recorded against the next row for the product within the same service group - correct output should look like this:

id,product_number, service_group,datetime,value
1,1234,1,2022-02-10 00:00:00,25
2,1234,1,2022-02-10 00:01:30,11
3,1234,1,2022-02-10 00:02:30,0
4,1234,2,2022-02-10 01:00:30,65
5,1234,2,2022-02-10 01:01:30,55
6,1234,2,2022-02-10 01:02:30,0

The below query is what seems to be hugely inefficient way of returning the correct results - what would be a better way to go about this in MySql? Thank you.

Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (
    Select b.value FROM products b
    Where b.product_number=a.product_number AND b.service_group=a.service_group
    AND b.datetime>a.datetime
    Order by b.datetime ASC
    Limit 1
    )
FROM products a```

Body:
If there's no skipped id (the number is in sequence) then you could probably use simple select like below

1.

Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (Select b.value FROM products b Where b.id = a.id+1)
FROM products a

Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    b.value
FROM products a
INNER JOIN products b ON b.id = a.id+1

Note that both SQL 1 and 2 is assuming your ID is primary key as I see that's an incrementing value

Either way you need to run an explain query so you could analyze which one is the most efficient one

And more importantly I suggest to update it if it's "wrongly recorded", you should put the your service on maintenance mode and do update+fix on the data using query

Edit:
based on your comment "Hi, Gunawan. Thank you for your suggestion. Unfortunately IDs will not be in sequences to support the proposed approach."

You could alter the subquery on (1) a bit to

Select b.value
FROM products b
Where b.id > a.id order by id asc limit 1

so it became

Select
    a.id,
    a.product_number,
    a.service_group,
    a.datetime,
    (Select b.value FROM products b Where b.id > a.id order by b.id asc limit 1)
FROM products a


问:
I am trying an async ajax call in MVC. The daata is not sent to server
The function sends data to server. The billItem stores the detail level entitity data. I am using MVC and i have Create method in controller class HomeController. I have two classes Bill and BillItem that is master and detail respectivelly.</p>
```<code>$('#submit').click(function () {
                var isValidItem = true;
                if ($('#BillNo').val() == 0) {
                    isValidItem = false;
                    $('#BillNo').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#BillNo').siblings('span.error').css('visibility', 'hidden');
                }
                if ($('#CustomerName').val() == '') {
                    isValidItem = false;
                    $('#CustomerName').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#CustomerName').siblings('span.error').css('visibility', 'hidden');
                }
                if ($('#Address').val() == '') {
                    isValidItem = false;
                    $('#Address').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#Address').siblings('span.error').css('visibility', 'hidden');
                }

                if (isValidItem) {
                    alert(billItem);
                     var data = {
                        BillNo: $('#txtBillNo').val(),
                        CustomerName: $('#txtCustomerName').val(),
                        Address: $('#txtAddress').val(),
                        Gender: $('input[name="Gender"]:checked').val(),
                        BillDetail: billItem
                    }
                    //$(this).val() = "Please wait...";
                    $ajax({
                        url: '/Home/Create',
                        type: "POST",
                        data: JSON.stringify(data),
                        dataType: "JSON",
                        contentType: "application/json",
                        success: function (d) {
                            if (d.status == true) {
                                alert("Successfully saved.");
                                billItem = [];
                                $('#txtBillNo').val('');
                                $('#txtCustomerName').val('');
                                $('#txtAddress').val('');
                            }
                            else {
                                alert("Error saving data.");
                            }
                            $('#submit').val('Save');
                        },
                        error: function () {
                            alert("Error saving data.");
                        }
                    });
                }
            });
</code>```

答:
Your Ajax call should look like this:

```<code>if (isValidItem) {
    alert(billItem);

     var data = {
        BillNo: $('#txtBillNo').val(),
        CustomerName: $('#txtCustomerName').val(),
        Address: $('#txtAddress').val(),
        Gender: $('input[name="Gender"]:checked').val(),
        BillDetail: billItem
    }

    //$(this).val() = "Please wait...";
    $ajax({
        url: "@Url.Action("Create", "Home")",
        type: "POST",
        data: {"json": JSON.stringify(data)},
        dataType: "JSON",
        success: function (d) {
            if (d.status == true) {
                alert("Successfully saved.");
                billItem = [];
                $('#txtBillNo').val('');
                $('#txtCustomerName').val('');
                $('#txtAddress').val('');
            }
            else {
                alert("Error saving data.");
            }
            $('#submit').val('Save');
        },
        error: function () {
            alert("Error saving data.");
        }
    });
}
</code>```

And your Controller method will get the data like this:

```<code>using System.Web.Script.Serialization;

[HttpPost]
public ActionResult Create(string json)
{
    var serializer = new JavaScriptSerializer();
    dynamic jsondata = serializer.Deserialize(json, typeof(object));

    //Get your variables here from AJAX call
    var BillNo = Convert.ToString(jsondata["BillNo"]);
    var CustomerName = Convert.ToString(jsondata["CustomerName"]);
    var Gender = Convert.ToString(jsondata["Gender"]);
    //Your logic

    return Json(new {status="true", msg= "Successful"});
}
</code>```

Body:
The function sends data to server. The billItem stores the detail level entitity data. I am using MVC and i have Create method in controller class HomeController. I have two classes Bill and BillItem that is master and detail respectivelly.

$('#submit').click(function () {
                var isValidItem = true;
                if ($('#BillNo').val() == 0) {
                    isValidItem = false;
                    $('#BillNo').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#BillNo').siblings('span.error').css('visibility', 'hidden');
                }
                if ($('#CustomerName').val() == '') {
                    isValidItem = false;
                    $('#CustomerName').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#CustomerName').siblings('span.error').css('visibility', 'hidden');
                }
                if ($('#Address').val() == '') {
                    isValidItem = false;
                    $('#Address').siblings('span.error').css('visibility', 'visible');
                }
                else {
                    $('#Address').siblings('span.error').css('visibility', 'hidden');
                }

                if (isValidItem) {
                    alert(billItem);
                     var data = {
                        BillNo: $('#txtBillNo').val(),
                        CustomerName: $('#txtCustomerName').val(),
                        Address: $('#txtAddress').val(),
                        Gender: $('input[name="Gender"]:checked').val(),
                        BillDetail: billItem
                    }
                    //$(this).val() = "Please wait...";
                    $ajax({
                        url: '/Home/Create',
                        type: "POST",
                        data: JSON.stringify(data),
                        dataType: "JSON",
                        contentType: "application/json",
                        success: function (d) {
                            if (d.status == true) {
                                alert("Successfully saved.");
                                billItem = [];
                                $('#txtBillNo').val('');
                                $('#txtCustomerName').val('');
                                $('#txtAddress').val('');
                            }
                            else {
                                alert("Error saving data.");
                            }
                            $('#submit').val('Save');
                        },
                        error: function () {
                            alert("Error saving data.");
                        }
                    });
                }
            });

Body:
Your Ajax call should look like this:

if (isValidItem) {
    alert(billItem);

     var data = {
        BillNo: $('#txtBillNo').val(),
        CustomerName: $('#txtCustomerName').val(),
        Address: $('#txtAddress').val(),
        Gender: $('input[name="Gender"]:checked').val(),
        BillDetail: billItem
    }

    //$(this).val() = "Please wait...";
    $ajax({
        url: "@Url.Action("Create", "Home")",
        type: "POST",
        data: {"json": JSON.stringify(data)},
        dataType: "JSON",
        success: function (d) {
            if (d.status == true) {
                alert("Successfully saved.");
                billItem = [];
                $('#txtBillNo').val('');
                $('#txtCustomerName').val('');
                $('#txtAddress').val('');
            }
            else {
                alert("Error saving data.");
            }
            $('#submit').val('Save');
        },
        error: function () {
            alert("Error saving data.");
        }
    });
}

And your Controller method will get the data like this:

using System.Web.Script.Serialization;

[HttpPost]
public ActionResult Create(string json)
{
    var serializer = new JavaScriptSerializer();
    dynamic jsondata = serializer.Deserialize(json, typeof(object));

    //Get your variables here from AJAX call
    var BillNo = Convert.ToString(jsondata["BillNo"]);
    var CustomerName = Convert.ToString(jsondata["CustomerName"]);
    var Gender = Convert.ToString(jsondata["Gender"]);
    //Your logic

    return Json(new {status="true", msg= "Successful"});
}


问:
Recoding rare categories of a variable to category -"other" based on condition
Need to transform variable below, based on category quantity in the dataset

so that categories that appear less than two times are re-named to category "other"

Data example

Desirable output

I used to use below chunk of code for such transformation but since I moved to R 4.05 it throws me an error.

```<code>levels(data$Country_of_origin) <-ifelse(table(data&Country_of_origin)>2,"OTHER",levels(data&Country_of_origin))
</code>```

答:
Not sure why your code stopped working but forcats::fct_lump_*() is a great option for this application. See small example here:

library(tidyverse)

d <- c('USA', 'USA', 'Germany', 'Japan', 'USA', 'USA') %>% factor()

# original distribution
table(d)
#> d
#> Germany   Japan     USA
#>       1       1       4

# lumpped distribution
fct_lump_min(d, min = 2) %>% table()
#> .
#>   USA Other
#>     4     2
```

Created on 2022-02-10 by the reprex package (v2.0.1)

Body:
Need to transform variable below, based on category quantity in the dataset

so that categories that appear less than two times are re-named to category "other"

Data example

Desirable output

I used to use below chunk of code for such transformation but since I moved to R 4.05 it throws me an error.

levels(data$Country_of_origin) <-ifelse(table(data&Country_of_origin)>2,"OTHER",levels(data&Country_of_origin))

Body:
Not sure why your code stopped working but forcats::fct_lump_*() is a great option for this application. See small example here:

library(tidyverse)

d <- c('USA', 'USA', 'Germany', 'Japan', 'USA', 'USA') %>% factor()

# original distribution
table(d)
#> d
#> Germany   Japan     USA
#>       1       1       4

# lumpped distribution
fct_lump_min(d, min = 2) %>% table()
#> .
#>   USA Other
#>     4     2

Created on 2022-02-10 by the reprex package (v2.0.1)


问:
Running an alias in a bash script gives me `<arguments>: command not found`
I have a script with an alias _test. It works fine, but before printing the output, it does <arguments>: command not found. For example, _test -h gives line 49: -h: command not found

This is a minimal example:

```<code>alias _test='
echo Hi
'
shopt -s expand_aliases

_test -h
</code>```

EDIT: For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.

EDIT 2: I just realized why I kept having recursion with my function/alias. I fixed it, and I switched back to a function, but this question may help someone else.

答:
Remove the newlines. As written, _test -h expands to this, with a blank line above and below the echo:

```<code>
echo Hi
-h
</code>```

Make it a one-line alias:

```<code>alias _test='echo Hi'
</code>```

In general, though, avoid aliases. They're really intended for convenience in interactive shells. In a script—or heck, even in interactive shells—it's better to use functions instead. For example:

```<code>_test() {
    echo Hi "$@"
}
</code>```

For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.

Were you trying to wrap an existing command, like this?

```<code>alias ls='ls --color=auto -F'
</code>```

If so you can use command to prevent a function calling itself recursively. The equivalent function would be:

```<code>ls() {
    command ls --color=auto -F "$@"
}
</code>```

command ls calls the ls command rather than the ls function we've just defined so we don't get stuck in an infinite recursive loop.

Body:
I have a script with an alias _test. It works fine, but before printing the output, it does <arguments>: command not found. For example, _test -h gives line 49: -h: command not found

This is a minimal example:

alias _test='
echo Hi
'
shopt -s expand_aliases

_test -h

EDIT: For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.

EDIT 2: I just realized why I kept having recursion with my function/alias. I fixed it, and I switched back to a function, but this question may help someone else.

Body:
Remove the newlines. As written, _test -h expands to this, with a blank line above and below the echo:

echo Hi
-h

Make it a one-line alias:

alias _test='echo Hi'

In general, though, avoid aliases. They're really intended for convenience in interactive shells. In a script—or heck, even in interactive shells—it's better to use functions instead. For example:

_test() {
    echo Hi "$@"
}

For those asking about using functions, I did in fact, used to have a function instead -- but it started to cause recursion problems. I just wanted something similar to a macro -- something that acts as if the text was inserted into the script.

Were you trying to wrap an existing command, like this?

alias ls='ls --color=auto -F'

If so you can use command to prevent a function calling itself recursively. The equivalent function would be:

ls() {
    command ls --color=auto -F "$@"
}

command ls calls the ls command rather than the ls function we've just defined so we don't get stuck in an infinite recursive loop.


问:
Flatten list of lists containing a single item

I have a list that consists of lists containing up to a single string, for example:

var fruits = new List<List<string>>
{
    new List<string>(),
    new List<string> { "Apple" },
    null,
    new List<string> { "Banana" },
};
```
<p>I would like to extract the strings from the list above, not allowing the lists containing the strings to have more than one item. That is, I need to have the following result:</p>
<pre class="lang-cs prettyprint-override"><code>{ "Apple", "Banana" }
</code>```

So far I have been trying the following:

var result = fruits
    .Where(x => x != null)
    .Select(x => x.SingleOrDefault())
    .Where(x => x != null);
```

Is there a simpler solution to do this?

答:
If I understand correctly you want to select all unique items in lists to a single list, you can use SelectMany() and Distinct() for that:

```<code>fruits.Where(x=> x != null).SelectMany(x=> x).Distinct();
</code>```

Body:
I have a list that consists of lists containing up to a single string, for example:

var fruits = new List<List<string>>
{
    new List<string>(),
    new List<string> { "Apple" },
    null,
    new List<string> { "Banana" },
};

I would like to extract the strings from the list above, not allowing the lists containing the strings to have more than one item. That is, I need to have the following result:

{ "Apple", "Banana" }

So far I have been trying the following:

var result = fruits
    .Where(x => x != null)
    .Select(x => x.SingleOrDefault())
    .Where(x => x != null);

Is there a simpler solution to do this?

Body:
If I understand correctly you want to select all unique items in lists to a single list, you can use SelectMany() and Distinct() for that:

fruits.Where(x=> x != null).SelectMany(x=> x).Distinct();


问:
Playing song one after another causes MP3Extractor error
```<code>@Override
public void onCreate(Bundle savedInstanceState) {
...
        mMediaPlayer = new MediaPlayer();

        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mediaPlayer) {
                playAudio(getNextAudioFile());
            }
        });
..
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if(mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}
    private boolean playAudio(String file) {
        if(file.isEmpty()) {
            return true;
        }

        if(mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
        }
    mMediaPlayer.reset();

        mAudioFile = new File(mBaseAudioDir, file);
        if(mAudioFile.canRead()) {
            try {
            mMediaPlayer.setDataSource(mAudioFile.getPath());
                mMediaPlayer.prepare();
            } catch (IllegalArgumentException e) {
                return false;
            } catch (IllegalStateException e) {
                return false;
            } catch (IOException e) {
                return false;
            }
            mMediaPlayer.start();
            return true;
        } else {
            return false;
        }
    }
</code>```

It works, but after song ends I have this error message in the log:

03-13 12:52:05.101:
  ERROR/MP3Extractor(34): Unable to
  resync. Signalling end of stream.
  03-13 13:16:59.585:
  INFO/StagefrightPlayer(34):
  setDataSource('/mnt/sdcard/Audio/sound.mp3')

答:
You should really not just have empty catch blocks,
you may be getting an explanation to that error but your just ignoring it
try this:</p>

```<code>     try {
        mMediaPlayer.setDataSource(mAudioFile.getPath());
            mMediaPlayer.prepare();
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "mMediaPlayer IllegalArgumentException " ,e);
            return false;
        } catch (IOException e) {
            Log.e(TAG, "mMediaPlayer IOException" ,e);
            return false;
        }
</code>```

ContentLicense: CC BY-SA 2.5

Body:
@Override
public void onCreate(Bundle savedInstanceState) {
...
        mMediaPlayer = new MediaPlayer();

        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mediaPlayer) {
                playAudio(getNextAudioFile());
            }
        });
..
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if(mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}
    private boolean playAudio(String file) {
        if(file.isEmpty()) {
            return true;
        }

        if(mMediaPlayer.isPlaying()) {
            mMediaPlayer.stop();
        }
    mMediaPlayer.reset();

        mAudioFile = new File(mBaseAudioDir, file);
        if(mAudioFile.canRead()) {
            try {
            mMediaPlayer.setDataSource(mAudioFile.getPath());
                mMediaPlayer.prepare();
            } catch (IllegalArgumentException e) {
                return false;
            } catch (IllegalStateException e) {
                return false;
            } catch (IOException e) {
                return false;
            }
            mMediaPlayer.start();
            return true;
        } else {
            return false;
        }
    }

It works, but after song ends I have this error message in the log:

03-13 12:52:05.101:
  ERROR/MP3Extractor(34): Unable to
  resync. Signalling end of stream.
  03-13 13:16:59.585:
  INFO/StagefrightPlayer(34):
  setDataSource('/mnt/sdcard/Audio/sound.mp3')

Body:
You should really not just have empty catch blocks,
you may be getting an explanation to that error but your just ignoring it
try this:

     try {
        mMediaPlayer.setDataSource(mAudioFile.getPath());
            mMediaPlayer.prepare();
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "mMediaPlayer IllegalArgumentException " ,e);
            return false;
        } catch (IOException e) {
            Log.e(TAG, "mMediaPlayer IOException" ,e);
            return false;
        }


问:
What is "range" actually? Is it a function?
One of the preferred way to loop through arrays and slices is to use range like this

arr = []int{1, 2}

for index, item := range arr {
  continue
}
```

I know how range works, I've been using it multiple times. But I'm still not sure what it is behind the scene. Is it a function and a modification of range(arr)? The fact that it returns 2 variables make me think that way, but I need a confirmation.

What's the implementation behind it?

答:
A for with a range clause iterates over arrays, slices, map, strings and values received on a channel. The range keyword is syntax used by the compiler to distinguish this type of iteration from other iteration in a for statement.

The compiler implements for with a range clause.  The specification describes for with a range clause in detail.

Body:
One of the preferred way to loop through arrays and slices is to use range like this

arr = []int{1, 2}

for index, item := range arr {
  continue
}

I know how range works, I've been using it multiple times. But I'm still not sure what it is behind the scene. Is it a function and a modification of range(arr)? The fact that it returns 2 variables make me think that way, but I need a confirmation.

What's the implementation behind it?


问:
Moving a rectangle up down left and right
I wanted to make a rectangle move in 4 directions with a click of a button on JavaScript. Only the Right and Down works and the other two does not work. I tried finding it on internet and so far had not have any luck.

var currentXpos = 0;

function moveRectRight() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}

function moveRectLeft() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}

function moveRectUp() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}

function moveRectDown() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#rectangle {
  background-color: red;
  width: 200px;
  height: 100px;
  margin-left: 0px;
}</code>```

<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />```

答:
Because margins in the HTML, depend on having a neightbor. So, you'll not see margin-right and margin-bottom working, hence you'll not see the box going up or left.

Instead, what you can do, is affect the same property with addition and substraction. For Y affect only margin-top and for X affect only margin-left

CSS Documentation

  <input type="button" value="Right" onclick="moveRectRight()" />
  <input type="button" value="Left" onclick="moveRectLeft()" />
  <input type="button" value="Up" onclick="moveRectUp()" />
  <input type="button" value="Down" onclick="moveRectDown()" />

```

Body:
I wanted to make a rectangle move in 4 directions with a click of a button on JavaScript. Only the Right and Down works and the other two does not work. I tried finding it on internet and so far had not have any luck.

var currentXpos = 0;

function moveRectRight() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}

function moveRectLeft() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}

function moveRectUp() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}

function moveRectDown() {
  var rect = document.getElementById('rectangle');
  currentXpos += 100; // move by 100 px to the right
  rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}

#rectangle {
  background-color: red;
  width: 200px;
  height: 100px;
  margin-left: 0px;
}

<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />

Body:
Because margins in the HTML, depend on having a neightbor. So, you'll not see margin-right and margin-bottom working, hence you'll not see the box going up or left.

Instead, what you can do, is affect the same property with addition and substraction. For Y affect only margin-top and for X affect only margin-left

CSS Documentation

<html>

<head>
  <style>
    #rectangle {
      background-color: red;
      width: 200px;
      height: 100px;
      margin-left: 0px;
    }
  </style>

</head>

<body>
    <div id='rectangle'>
    </div>
  <input type="button" value="Right" onclick="moveRectRight()" />
  <input type="button" value="Left" onclick="moveRectLeft()" />
  <input type="button" value="Up" onclick="moveRectUp()" />
  <input type="button" value="Down" onclick="moveRectDown()" />
  <script>
    var currentXpos = 0;
    function moveRectRight() {
      var rect = document.getElementById('rectangle');
      console.log(rect)
      currentXpos += 100; // move by 100 px to the right
      rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
    }
    function moveRectLeft() {
      var rect = document.getElementById('rectangle');
      currentXpos -= 100; // move by 100 px to the right
      rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
    }
    function moveRectUp() {
      var rect = document.getElementById('rectangle');
      currentXpos -= 100; // move by 100 px to the right
      rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
    }
    function moveRectDown() {
      var rect = document.getElementById('rectangle');
      currentXpos += 100; // move by 100 px to the right
      rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
    }

  </script>
</body>

</html>


问:
time.time() or time.perf_counter() — which is faster?
Context: I'm implementing a memory cache with TTLs in my Python project, and it has to withstand considerable throughput. To determine when a cache record goes stale, I save it with a timestamp, and when I retrieve it later I check this timestamp against the current time. If the difference is above the threshold, the record is stale and should be discarded.

Question: time.time() or time.perf_counter() — which function returns its value faster? Is the difference considerable or negligible?

答:
I did a benchmark to find out

> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 132 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 69.6 nsec per loop
> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 126 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 75.9 nsec per loop
> py -V
Python 3.10.1
```

We can conclude that time.time() is nearly twice as fast than time.perf_counter()

However the magnitude of the difference is very low, ~56 nanosec

To put that into perspective it is only ~168 clock cycles slower on a 3ghz cpu

Body:
I did a benchmark to find out

> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 132 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 69.6 nsec per loop
> py -m timeit -s "from time import perf_counter as time" -n 10000000 "time()"
10000000 loops, best of 5: 126 nsec per loop
> py -m timeit -s "from time import time" -n 10000000 "time()"
10000000 loops, best of 5: 75.9 nsec per loop
> py -V
Python 3.10.1

We can conclude that time.time() is nearly twice as fast than time.perf_counter()

However the magnitude of the difference is very low, ~56 nanosec

To put that into perspective it is only ~168 clock cycles slower on a 3ghz cpu


问:
Verify valid date using PHP's DateTime class
Below is how I previously verified dates.  I also had my own functions to convert date formats, however, now am using PHP's DateTime class so no longer need them.  How should I best verify a valid date using DataTime? Please also let me know whether you think I should be using DataTime in the first place.  Thanks

PS.  I am using Object oriented style, and not Procedural style.

```<code>static public function verifyDate($date)
{
  //Given m/d/Y and returns date if valid, else NULL.
  $d=explode('/',$date);
  return ((isset($d[0])&&isset($d[1])&&isset($d[2]))?(checkdate($d[0],$d[1],$d[2])?$date:NULL):NULL);
}
</code>```

答:
With the following an empty string like '' or 0 or '0000-00-00 00:00:00' is false</p>
```<code>$valid = strtotime($date) > 0;
</code>```

Body:
Below is how I previously verified dates.  I also had my own functions to convert date formats, however, now am using PHP's DateTime class so no longer need them.  How should I best verify a valid date using DataTime? Please also let me know whether you think I should be using DataTime in the first place.  Thanks

PS.  I am using Object oriented style, and not Procedural style.

static public function verifyDate($date)
{
  //Given m/d/Y and returns date if valid, else NULL.
  $d=explode('/',$date);
  return ((isset($d[0])&&isset($d[1])&&isset($d[2]))?(checkdate($d[0],$d[1],$d[2])?$date:NULL):NULL);
}

Body:
With the following an empty string like '' or 0 or '0000-00-00 00:00:00' is false

$valid = strtotime($date) > 0;