问:
Efficiently fetch glTF data from an API GET endpoint within a CesiumJS client app
I am trying to build a small sandbox CesiumJS app for pedagogic purposes.

For that, I need to query some small glTF assets (2 small flat squares build from 4 simple triangles) available at an existing API GET endpoint, e.g: https://my-server.org/api/v2/data/collection/8/gltf/item.gltf. Then I would like to naturally display them within my Cesium app.

From this simple but yet fully functional answer: https://stackoverflow.com/a/71088611/6630397 I am able to fetch a JSON response from the API.

But when passing the full URL of a glTF asset, using for example the fetchBlob() function, it says:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://my-server.org/api/v2/data/collection/8/gltf/item.gltf. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

Please note that if I click that link in my browser console, it successfully opens a pop-up for actually downloading the glTF file.

So, is it possible to make the same append automatically within my client application so that the glTF file is directly loaded in the Cesium globe? (if absolutely needed, a temporary storage in a local folder on the disk is OK)

Here is the documentation pages on which I rely so far: https://cesium.com/learn/cesiumjs/ref-doc/Resource.html but I cannot find and way to fetch a glTF object from a URL.

Maybe there is something to do with the native Fetch API? But my first attempt is not successful either, e.g.:

glTFFileURL = "https://my-server.org/api/v2/data/collection/8/gltf/item.gltf";

let glTFPromise = fetch(glTFFileURL);
console.log("glTFPromise:",glTFPromise);
glTFPromise.then((res) => {
  console.log(res);
}).otherwise(err => {
  console.log(err);
});
```
<p>which returns all this stack trace:</p>
```glTFPromise: // <- this is the console.log() output
  Promise { <state>: "pending"
  <state>: "rejected
  <reason>: TypeError: NetworkError when attempting to fetch resource.
  columnNumber: 0
  fileName: ""
  lineNumber: 0
  message: "NetworkError when attempting to fetch resource."
  stack: ""
  (...)

(!) Uncaught (in promise) TypeError: glTFPromise.then(...).otherwise is not a function
(...reference to the .otherwise() of the above code)

(!) Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote
    resource at https://my-server.org/api/v2/data/collection/8/gltf/item.gltf.
    (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

(!) Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
```

Doesn't the server.cjs already allows all the necessary for this to work out of the box: https://github.com/CesiumGS/cesium/blob/6f4c4cc7019aad071086effd575a146b76523e3c/server.cjs#L69-L76 ?

CORS error ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin

答:
This is not a Cesium js-specific issue.

Your server has to allow CORS.

Body:
I am trying to build a small sandbox CesiumJS app for pedagogic purposes.

For that, I need to query some small glTF assets (2 small flat squares build from 4 simple triangles) available at an existing API GET endpoint, e.g: https://my-server.org/api/v2/data/collection/8/gltf/item.gltf. Then I would like to naturally display them within my Cesium app.

From this simple but yet fully functional answer: https://stackoverflow.com/a/71088611/6630397 I am able to fetch a JSON response from the API.

But when passing the full URL of a glTF asset, using for example the fetchBlob() function, it says:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://my-server.org/api/v2/data/collection/8/gltf/item.gltf. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

Please note that if I click that link in my browser console, it successfully opens a pop-up for actually downloading the glTF file.

So, is it possible to make the same append automatically within my client application so that the glTF file is directly loaded in the Cesium globe? (if absolutely needed, a temporary storage in a local folder on the disk is OK)

Here is the documentation pages on which I rely so far: https://cesium.com/learn/cesiumjs/ref-doc/Resource.html but I cannot find and way to fetch a glTF object from a URL.

Maybe there is something to do with the native Fetch API? But my first attempt is not successful either, e.g.:

glTFFileURL = "https://my-server.org/api/v2/data/collection/8/gltf/item.gltf";

let glTFPromise = fetch(glTFFileURL);
console.log("glTFPromise:",glTFPromise);
glTFPromise.then((res) => {
  console.log(res);
}).otherwise(err => {
  console.log(err);
});

which returns all this stack trace:

glTFPromise: // <- this is the console.log() output
  Promise { <state>: "pending"
  <state>: "rejected
  <reason>: TypeError: NetworkError when attempting to fetch resource.
  columnNumber: 0
  fileName: ""
  lineNumber: 0
  message: "NetworkError when attempting to fetch resource."
  stack: ""
  (...)

(!) Uncaught (in promise) TypeError: glTFPromise.then(...).otherwise is not a function
(...reference to the .otherwise() of the above code)

(!) Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote
    resource at https://my-server.org/api/v2/data/collection/8/gltf/item.gltf.
    (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

(!) Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.

Doesn't the server.cjs already allows all the necessary for this to work out of the box: https://github.com/CesiumGS/cesium/blob/6f4c4cc7019aad071086effd575a146b76523e3c/server.cjs#L69-L76 ?

CORS error ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin


来源: stackexchange

问:
Get download count of downloadable product to display in Woocommerce
I am hoping to display how many ppl hv downloaded the product,
notice, not the number of sales.
Because sometimes I will offer the product free,
and I was hoping to manipulate this number with each click.

The first part I tried to display the number of downloads:

```<code>function add_download_count(){
    global $product;
    if ($product->is_downloadable('yes')){
$query = "SELECT SUM( download_count ) AS count FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = $product->id";
    $count = $wpdb->get_var( $query );
        echo "Downloads: ".$count;
    }
}
add_action("woocommerce_before_single_product_summary", "add_download_count");
</code>```

I learnt this from another post here:
Download Count on WooCommerce Free Product
it's a very dated post so maybe something is changed now that I tried the code with with no avail because it returns an error: Call to a member function get_var() on null

Second Part, I hope to add the number of downloads by clicking the following:

```<code>foreach( $downloads as $key => $each_download ) {
  echo '<a href="'.$each_download["file"].'">Download</a>';
}
</code>```

however I am not sure how to make that happen? I am thinking if it is possible to click and trigger to update a +1 to the download_count.

Or am I in the wrong logic here?

UPDATE

After tinkering a bit around, i found this method doesn't work.

not even putting global $wpdb; to it.

The reason for adding the number to download count after click is that:

user download through the  link generated by $product->get_downloads() doesnt go through the cart system of WooCommerce.

thus it doesnt reflect automatically on the numbers of purchase or downloads.

I think this is bad logic and perhaps not a good way to achieve the idea.
I move on and tried to utilize the default $product->get_total_sales() instead.
This seemed to be a safer way and as intended by the original design.

I successfully display number of sales easily by:

```<code>function add_download_count(){
    global $product;
    $count = $product->get_total_sales();
    echo "<span id='downloadcount' data-downloadcount='".$count."'><span class='enclass'>Downloads:</span> ".$count."</span>";
}
add_action("woocommerce_single_product_summary", "add_download_count", 15);
</code>```

As you can see I tried to store the count number in data-count, so it can be manipulated through AJAX.

```<code>
jQuery(document).ready(function($) {

    $( ".downloadbtn_now" ).click(function() {

    //aJAX
    let wasdownloadcount = parseInt($( "#downloadcount" ).data( "downloadcount" ) ) ;
    let downloadcount = wasdownloadcount + 1;
     $.ajax({
            type: "POST",url: "<? admin_url('admin-ajax.php') ?>",
            dataType: "json",
            data: { downloadcount: downloadcount, action: 'download_count' }
          }).done(function() {
            alert( "Data was " + wasdownloadcount + " but now is: " +downloadcount );
          });

    });

});

</code>```

I got:

POST http://localhost/wp-admin/admin-ajax.php 500 (Internal Server Error)

and I am not sure how to move forward from here.

my function call back in functions.php as follow, it uses the default function in woocommerce set_total_sales:

```<code>//AJAX
add_action('wp_ajax_download_count', 'download_count_callback');
 add_action('wp_ajax_nopriv_download_count', 'download_count_callback');
function download_count_callback(){
    $downloadcount = $_POST['downloadcount'];
set_total_sales($downloadcount);
    die();
}
</code>```

Where's my problem?

答:
I added this code and it works very well

```<code>function add_download_count(){ global $product; $count = $product->get_total_sales(); echo “ Downloads:  ”.$count.” ”; } add_action(“woocommerce_single_product_summary”, “add_download_count”, 15);
</code>```

That’s what it looks like

ContentLicense: CC BY-SA 4.0

Body:
I am hoping to display how many ppl hv downloaded the product,
notice, not the number of sales.
Because sometimes I will offer the product free,
and I was hoping to manipulate this number with each click.

The first part I tried to display the number of downloads:

function add_download_count(){
    global $product;
    if ($product->is_downloadable('yes')){
$query = "SELECT SUM( download_count ) AS count FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = $product->id";
    $count = $wpdb->get_var( $query );
        echo "Downloads: ".$count;
    }
}
add_action("woocommerce_before_single_product_summary", "add_download_count");

I learnt this from another post here:
Download Count on WooCommerce Free Product
it's a very dated post so maybe something is changed now that I tried the code with with no avail because it returns an error: Call to a member function get_var() on null

Second Part, I hope to add the number of downloads by clicking the following:

foreach( $downloads as $key => $each_download ) {
  echo 'Download';
}

however I am not sure how to make that happen? I am thinking if it is possible to click and trigger to update a +1 to the download_count.

Or am I in the wrong logic here?

UPDATE

After tinkering a bit around, i found this method doesn't work.

not even putting global $wpdb; to it.

The reason for adding the number to download count after click is that:

user download through the  link generated by $product->get_downloads() doesnt go through the cart system of WooCommerce.

thus it doesnt reflect automatically on the numbers of purchase or downloads.

I think this is bad logic and perhaps not a good way to achieve the idea.
I move on and tried to utilize the default $product->get_total_sales() instead.
This seemed to be a safer way and as intended by the original design.

I successfully display number of sales easily by:

function add_download_count(){
    global $product;
    $count = $product->get_total_sales();
    echo "Downloads: ".$count."";
}
add_action("woocommerce_single_product_summary", "add_download_count", 15);

As you can see I tried to store the count number in data-count, so it can be manipulated through AJAX.

jQuery(document).ready(function($) {

    $( ".downloadbtn_now" ).click(function() {

    //aJAX
    let wasdownloadcount = parseInt($( "#downloadcount" ).data( "downloadcount" ) ) ;
    let downloadcount = wasdownloadcount + 1;
     $.ajax({
            type: "POST",url: "<? admin_url('admin-ajax.php') ?>",
            dataType: "json",
            data: { downloadcount: downloadcount, action: 'download_count' }
          }).done(function() {
            alert( "Data was " + wasdownloadcount + " but now is: " +downloadcount );
          });

    });

});

I got:

POST http://localhost/wp-admin/admin-ajax.php 500 (Internal Server Error)

and I am not sure how to move forward from here.

my function call back in functions.php as follow, it uses the default function in woocommerce set_total_sales:

//AJAX
add_action('wp_ajax_download_count', 'download_count_callback');
 add_action('wp_ajax_nopriv_download_count', 'download_count_callback');
function download_count_callback(){
    $downloadcount = $_POST['downloadcount'];
set_total_sales($downloadcount);
    die();
}

Where's my problem?

Body:
I added this code and it works very well

function add_download_count(){ global $product; $count = $product->get_total_sales(); echo “ Downloads:  ”.$count.” ”; } add_action(“woocommerce_single_product_summary”, “add_download_count”, 15);

That’s what it looks like


问:
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.

答:
You can use Numba to make this code much much faster. Numba use a just-in-time compiler to generate a very fast native code. Numba does not supports Pandas but the columns can be converted to Numpy view and Numba is able to works on them very quickly.

Assuming the datetime indexes are properly sorted in the input dataframe (which appears to be the case regarding the Pandas code), you can write the following Numba function:

import numba as nb

# Note: if you know that there is no NaN & Inf values then you can
# use the additional flag fastmath=True so to generate a faster code.
# Check the results with this flag to be safe.
@nb.njit('void(float64[:], float64[:], float64[:], int64[:], float64[:], float64[:], float64[:])')
def compute(L, m, k, f, soc, charge, discharge):
    n = L.shape[0]
    assert m.size == n and k.size == n and f.size == n
    assert soc.size == n and charge.size == n and discharge.size == n

    for i in range(n):
        if i == 0:
            soc[i] = bp_soct0
            charge[i] = min(L[i], (bp_energy - bp_soct0) * 4.0, bp_power) * bp_efficiency if L[i] >= 0.0 else 0.0
            discharge[i] = -min(m[i], 4.0 * bp_soct0 - 4.0 * (bp_minsoc * bp_energy), bp_power) if m[i] >= 0.0 else 0.0
        else:
            soc[i] = soc[i-1] + (charge[i-1] + discharge[i-1]) * 0.25
            charge[i] = min(L[i], (bp_energy - soc[i]) * 4.0, bp_power) * bp_efficiency if L[i] >= 0.0 else 0.0
            discharge[i] = -min(m[i], 4.0 * soc[i] - 4.0 * (bp_minsoc * bp_energy), bp_power) if m[i] >= 0.0 else 0.0
```
<p><code>@nb.njit</code> is a decorator that compiles the Python function into a fast native code. Its string parameter is the signature of the function specifying the parameter types and the return type of the function. The types may be different on you machine. Note that it is better to work with well-defined types by manually casting Pandas columns if necessary. It can be not only fast, but also take less memory space and remove possible unexpected issues (eg. floating-point rounding).</p>
<p>The Numba code works on view of each columns of the copied Pandas dataframe called <code>cp</code>. The wrapping code is the following:</p>
<pre class="lang-py prettyprint-override"><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.0
cp["Charge (kW)"] = 0.0
cp["Discharge (kW)"] = 0.0

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

# 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

# Extract Numpy views from the Pandas dataframe (20 us)
L = cp["Injection (kW)"].to_numpy()
m = cp["Grid Consumption (kW)"].to_numpy()
k = cp["Auto-consumption (kW)"].to_numpy()
f = cp["Consumption (kW)"].to_numpy()
soc = cp["State of charge (kW)"].to_numpy()
charge = cp["Charge (kW)"].to_numpy()
discharge = cp["Discharge (kW)"].to_numpy()

# Mutate/Fill the columns (2 us)
compute(L, m, k, f, soc, charge, discharge)

end1 = tt() - start1
print(f"Numba took {end1:.2f} seconds")
</code>```

Benchmark

On my machine, the initial Pandas code (in EDIT 2) takes 70 ms. The Numba compute function takes only 0.002 ms and the wrapping code calling to_numpy takes only 0.020 ms! This means the current Numba code is roughly 3200 times faster on the provided small example Pandas dataframe! Moreover, the wrapping code should take a constant time independent of the input size. This means that only the time of the compute function should take a significant time in the measured section on a bigger dataframe.

In fact, I tried to create a 100 times bigger input dataframe with values of the small one repeated for 3 months and here are performance results on my machine:

Initial code in ("EDIT 2"):      6830   ms
This Numba code:                    0.1 ms
```

Thus, on a bigger dataset, Numba is 68300 time faster!

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:
You can use Numba to make this code much much faster. Numba use a just-in-time compiler to generate a very fast native code. Numba does not supports Pandas but the columns can be converted to Numpy view and Numba is able to works on them very quickly.

Assuming the datetime indexes are properly sorted in the input dataframe (which appears to be the case regarding the Pandas code), you can write the following Numba function:

import numba as nb

# Note: if you know that there is no NaN & Inf values then you can
# use the additional flag fastmath=True so to generate a faster code.
# Check the results with this flag to be safe.
@nb.njit('void(float64[:], float64[:], float64[:], int64[:], float64[:], float64[:], float64[:])')
def compute(L, m, k, f, soc, charge, discharge):
    n = L.shape[0]
    assert m.size == n and k.size == n and f.size == n
    assert soc.size == n and charge.size == n and discharge.size == n

    for i in range(n):
        if i == 0:
            soc[i] = bp_soct0
            charge[i] = min(L[i], (bp_energy - bp_soct0) * 4.0, bp_power) * bp_efficiency if L[i] >= 0.0 else 0.0
            discharge[i] = -min(m[i], 4.0 * bp_soct0 - 4.0 * (bp_minsoc * bp_energy), bp_power) if m[i] >= 0.0 else 0.0
        else:
            soc[i] = soc[i-1] + (charge[i-1] + discharge[i-1]) * 0.25
            charge[i] = min(L[i], (bp_energy - soc[i]) * 4.0, bp_power) * bp_efficiency if L[i] >= 0.0 else 0.0
            discharge[i] = -min(m[i], 4.0 * soc[i] - 4.0 * (bp_minsoc * bp_energy), bp_power) if m[i] >= 0.0 else 0.0

@nb.njit is a decorator that compiles the Python function into a fast native code. Its string parameter is the signature of the function specifying the parameter types and the return type of the function. The types may be different on you machine. Note that it is better to work with well-defined types by manually casting Pandas columns if necessary. It can be not only fast, but also take less memory space and remove possible unexpected issues (eg. floating-point rounding).

The Numba code works on view of each columns of the copied Pandas dataframe called cp. The wrapping code is the following:

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.0
cp["Charge (kW)"] = 0.0
cp["Discharge (kW)"] = 0.0

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

# 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

# Extract Numpy views from the Pandas dataframe (20 us)
L = cp["Injection (kW)"].to_numpy()
m = cp["Grid Consumption (kW)"].to_numpy()
k = cp["Auto-consumption (kW)"].to_numpy()
f = cp["Consumption (kW)"].to_numpy()
soc = cp["State of charge (kW)"].to_numpy()
charge = cp["Charge (kW)"].to_numpy()
discharge = cp["Discharge (kW)"].to_numpy()

# Mutate/Fill the columns (2 us)
compute(L, m, k, f, soc, charge, discharge)

end1 = tt() - start1
print(f"Numba took {end1:.2f} seconds")

Benchmark

On my machine, the initial Pandas code (in EDIT 2) takes 70 ms. The Numba compute function takes only 0.002 ms and the wrapping code calling to_numpy takes only 0.020 ms! This means the current Numba code is roughly 3200 times faster on the provided small example Pandas dataframe! Moreover, the wrapping code should take a constant time independent of the input size. This means that only the time of the compute function should take a significant time in the measured section on a bigger dataframe.

In fact, I tried to create a 100 times bigger input dataframe with values of the small one repeated for 3 months and here are performance results on my machine:

Initial code in ("EDIT 2"):      6830   ms
This Numba code:                    0.1 ms

Thus, on a bigger dataset, Numba is 68300 time faster!


问:
Round up from .5 in a %
Ceiling rounds up no matter if you get .1, .3, .5, .7. or whatever the value is for the decimal.

I need to know how to only round up if you have .5.  So for example [number].5 round up.

Anyone know how to do this?

答:
Math.Round(0.5) works as expected.

EDIT

Math.Round(0.5, MidpointRounding.AwayFromZero) rounds up if you're on 0.5

ContentLicense: CC BY-SA 3.0

Title: Round up from .5 in a %


问:
Uncaught TypeError: emit is not a function in vue3
when I write this code in vue 3 setup code block to get the input value follow this answer, this is part of the code:

```<code>import { defineComponent } from "vue";
import { defineProps, defineEmits } from 'vue'

export default defineComponent({
  setup() {
    const props = defineProps({
      modelValue: String
    })
    const emit = defineEmits(['update:modelValue'])
    function updateValue(value: any) {
      emit('update:modelValue', value)
    }
}
</code>```

the app show error when running:

```<code>option.js:17388 Uncaught TypeError: emit is not a function
    at Proxy.updateValue (option.js:17388:13)
    at onInput._cache.<computed>._cache.<computed> (option.js:17428:78)
    at callWithErrorHandling (option.js:7359:22)
    at callWithAsyncErrorHandling (option.js:7368:21)
    at HTMLInputElement.invoker (option.js:15384:90)
</code>```

I have defined the emit, why still tell me emit is not a function? This is my full code of the vue3 component:

```<code><template>
  <div id="app">
    <div id="wrap">
      <label>
        {{ username }}
      </label>
      <ul class="nav nav-tabs">
        <li>
          <input
          :value="props"
          placeholder="username"
          v-on:input="updateValue($event.target.value)"/>
          <input v-model="password" placeholder="password" />
          <button @click="login">Login</button>
        </li>
      </ul>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import { defineProps, defineEmits } from 'vue'

export default defineComponent({
  setup() {
    const props = defineProps({
      modelValue: String
    })
    const emit = defineEmits(['update:modelValue'])
    function updateValue(value: any) {
      emit('update:modelValue', value)
    }

    const login = () => {
      debugger
      alert(props.modelValue);
    };
    debugger

    return {
      login,
      updateValue,
      props
    };

  },
  components: {},
});
</script>

<style lang="scss" scoped>
</style>
</code>```

I want to get the user input username from the template input.Seems did not work this way. what should I do to fix this problem? I have tried to upgrade the @vue/compiler-sfc to 3.2.31, still did not fix this problem.

答:
defineEmits and defineProps are only used in script setup, the first example should define the props as option and the emit is the second parameter of the setup hook :

import { defineComponent } from "vue";

export default defineComponent({
   props:{
   modelValue: String
  },
  setup(props,{emit}) {

    function updateValue(value: any) {
      emit('update:modelValue', value)
    }
}

```

Body:
when I write this code in vue 3 setup code block to get the input value follow this answer, this is part of the code:

import { defineComponent } from "vue";
import { defineProps, defineEmits } from 'vue'

export default defineComponent({
  setup() {
    const props = defineProps({
      modelValue: String
    })
    const emit = defineEmits(['update:modelValue'])
    function updateValue(value: any) {
      emit('update:modelValue', value)
    }
}

the app show error when running:

option.js:17388 Uncaught TypeError: emit is not a function
    at Proxy.updateValue (option.js:17388:13)
    at onInput._cache.<computed>._cache.<computed> (option.js:17428:78)
    at callWithErrorHandling (option.js:7359:22)
    at callWithAsyncErrorHandling (option.js:7368:21)
    at HTMLInputElement.invoker (option.js:15384:90)

I have defined the emit, why still tell me emit is not a function? This is my full code of the vue3 component:

<template>

        {{ username }}

          <input
          :value="props"
          placeholder="username"
          v-on:input="updateValue($event.target.value)"/>
          <input v-model="password" placeholder="password" />
          <button @click="login">Login</button>

</template>

I want to get the user input username from the template input.Seems did not work this way. what should I do to fix this problem? I have tried to upgrade the @vue/compiler-sfc to 3.2.31, still did not fix this problem.


问:
TypeORM Connection "default" was not found when using a routes file and repository pattern
I have a TS project where I'm using TypeORM. I'm using Repository pattern so I have layers: Controller -> Service -> Repository.

The Controller constructor initialize the Service class which initialize Repository class, where the constructor is:

constructor(){
    this.ormRepository = getRepository(TypeormEntity)
}
```
<p>This works fine when I create the routes in the <code>index.ts</code> like this:</p>
```createConnection().then(() => {
  const controller = new MyController()
  app.get('/', controller.getSomething);
})
```
<p>The connection is created and then I initialize the class using <code>new MyController()</code>.</p>
<p>The problem is when I want to get the routes in another file. I want to get this structure folder:</p>
```src
 |--> index.ts
 |--> routes
      |--> v1
           |--> router.ts
           |--> value
                 |--> value.route.ts
      |--> v2
           |--> ...
```
<p>So, to achieve this, the <code>index.ts</code> import the routes. But the problem is, as the import is done, the <code>MyController()</code> constructor is executed and the execution fails.</p>
<p>So I want to have something like this in <code>index.ts</code></p>
<pre class="lang-js prettyprint-override"><code>import * as express from 'express'
import { createConnection } from "typeorm";
import Router from './routes/v1/router'

const app = express()
createConnection().then(() => {
  app.use('/', Router)
  app.listen(port)
})
</code>```

Also, following the import call, the file router.ts in routes/v1 is:

import { json, Router } from 'express'
import valueRouter from './value/value.route'

const router = Router()
router.use(json())
router.use('/value', valueRouter)

export default router
```
<p>This is to add a "prefix" to all routes depending the resource they call.</p>
<p>And <code>value.route.ts</code> is where the controller is initialized and fails.</p>
<pre class="lang-js prettyprint-override"><code>import { Router } from "express";
import ValueController from '../../../controller/value.controller'

const router = Router()
const vc = new ValueController()
router.get('/',vc.getSomething)

export default router
</code>```

I've tested deleting the constructor and the project intializes ok, so the problem is the repository initialization accross Controller & Service.

How can I achieve this?

Thanks in advance.

答:
Finally I solved my own issue using dynamic imports.

Now my index.ts looks like this:

createConnection().then(() => {
  import('./routes/v1/router').then((router: any) => {
    app.use('/', router.default)
    app.listen(port)
  })
})
```

Which I think is much cleaner than having all routes added in this file. Calling routes in an external file I can manage a huge amount and maintain a clean structure.

Body:
I have a TS project where I'm using TypeORM. I'm using Repository pattern so I have layers: Controller -> Service -> Repository.

The Controller constructor initialize the Service class which initialize Repository class, where the constructor is:

constructor(){
    this.ormRepository = getRepository(TypeormEntity)
}

This works fine when I create the routes in the index.ts like this:

createConnection().then(() => {
  const controller = new MyController()
  app.get('/', controller.getSomething);
})

The connection is created and then I initialize the class using new MyController().

The problem is when I want to get the routes in another file. I want to get this structure folder:

src
 |--> index.ts
 |--> routes
      |--> v1
           |--> router.ts
           |--> value
                 |--> value.route.ts
      |--> v2
           |--> ...

So, to achieve this, the index.ts import the routes. But the problem is, as the import is done, the MyController() constructor is executed and the execution fails.

So I want to have something like this in index.ts

import * as express from 'express'
import { createConnection } from "typeorm";
import Router from './routes/v1/router'

const app = express()
createConnection().then(() => {
  app.use('/', Router)
  app.listen(port)
})

Also, following the import call, the file router.ts in routes/v1 is:

import { json, Router } from 'express'
import valueRouter from './value/value.route'

const router = Router()
router.use(json())
router.use('/value', valueRouter)

export default router

This is to add a "prefix" to all routes depending the resource they call.

And value.route.ts is where the controller is initialized and fails.

import { Router } from "express";
import ValueController from '../../../controller/value.controller'

const router = Router()
const vc = new ValueController()
router.get('/',vc.getSomething)

export default router

I've tested deleting the constructor and the project intializes ok, so the problem is the repository initialization accross Controller & Service.

How can I achieve this?

Thanks in advance.

Body:
Finally I solved my own issue using dynamic imports.

Now my index.ts looks like this:

createConnection().then(() => {
  import('./routes/v1/router').then((router: any) => {
    app.use('/', router.default)
    app.listen(port)
  })
})

Which I think is much cleaner than having all routes added in this file. Calling routes in an external file I can manage a huge amount and maintain a clean structure.


问:
WPF - can't display page content
I'm trying to display a wpf page inside a wpf window (to reproduce some bug in an isolated environment) and I'm unable to see the page inside the window.

My code is quite simple:

MainWindow.xaml:

```<code> <ContentPresenter
        Content="{Binding ElementName=Root, Path=MyPage}"
        ContentTemplate="{Binding ElementName=Root, Path=MyPage.TT}"
        />
</code>```

MainWindow.xaml.cs:

```<code> public MainWindow()
    {
        InitializeComponent();
        this.MyPage = new Page1();
    }
</code>```

Page1.xaml:

```<code><DataTemplate x:Name="TT">
<Grid>
    <TextBlock Text="doodle dood doodle da"></TextBlock>
</Grid>
</DataTemplate>
</code>```

Any Idea why MainWindow appears empty?

Thanks,
Li

答: Path=MyPage.TT looks for a property called TT, TT in all likelihood is not a property.

Title: WPF - can't display page content

Body:
I'm trying to display a wpf page inside a wpf window (to reproduce some bug in an isolated environment) and I'm unable to see the page inside the window.

My code is quite simple:

MainWindow.xaml:

 <ContentPresenter
        Content="{Binding ElementName=Root, Path=MyPage}"
        ContentTemplate="{Binding ElementName=Root, Path=MyPage.TT}"
        />

MainWindow.xaml.cs:

 public MainWindow()
    {
        InitializeComponent();
        this.MyPage = new Page1();
    }

Page1.xaml:

<DataTemplate x:Name="TT">
<Grid>
    <TextBlock Text="doodle dood doodle da"></TextBlock>
</Grid>
</DataTemplate>

Any Idea why MainWindow appears empty?

Thanks,
Li


问:
Python: How to solve bracket not closed error
following a tutorial I'm getting error "(" is not closed while using the exact same code:

```<code>compiled_sol = compile_standard(
  {
      "language": "Solidity",
      "sources": {"SimpleStorage.sol": {"content" = simple_storage_file}}
  }
)
</code>```

don't know where it's going wrong getting these errors:

```<code>"{" was not closedPylance
Expected parameter namePylance
</code>```

and

```<code>Expected parameter namePylance
</code>```

答: try to replace "=" for ":" I hope this solves the problem.</p>

Body:
following a tutorial I'm getting error "(" is not closed while using the exact same code:

compiled_sol = compile_standard(
  {
      "language": "Solidity",
      "sources": {"SimpleStorage.sol": {"content" = simple_storage_file}}
  }
)

don't know where it's going wrong getting these errors:

"{" was not closedPylance
Expected parameter namePylance

and

Expected parameter namePylance


问:
PermissionError: [Errno 13] when converted to exe
I have just converted my main python file in my project to an executable and it now returns a permission error when the exe is run. When the source code is run, it works fine. The error message is pasted below:

Error

Thanks for any help.

答:
This is a common problem when receiving permission errors that usually has to do with anti-virus.

Try this and it should work. This is the solution that worked for me when I first ran into the same issue with Pyinstaller.

In a CMD or a powershell, enter this below replacing "app_name_here" with what you'd like to name the exe, and replace the example path with your path to the .py file that you're trying to convert.

python -m PyInstaller --name "App_name_here" "C:\Users\user1\Documents\Python\myapp\main.py


问:
Private properties in Python
I am very new to Python. Here is some test code:

```<code>class Test():
  def __init__(self,num,option):
    self.__num = num
    self.option = option
  def getNum(self):
    return self.__num
  def getOption(self):
     return self.option

my_num = Test(77,1)
print(my_num.getNum())    // 77
print(my_num._Test__num)  // 77
print(my_num.__num)       // Attribute error
</code>```

My question is:

Why my_num.getNum() returns 77?

Why self.__num through getNum has value and my_num.__num returns error?

self in self.__num points to my_num, isn't it? Since __num is a private property, how is it accessible through self whereas self points to an object?

答:
In the constructor, you're passing value 77, which gets assigned to self.__num.  Later when you request .getNum() it's simply passing the same self.__num back to you, so you get 77 back.  The best way to think of self is like this in other languages, it's referencing the instantiated object itself.

You get an error on calling .__num directly because of name mangling, instead it's been renamed to ._Test__num.

What you're encountering is something called name mangling.

Specifically:

A double underscore prefix causes the Python interpreter to rewrite the attribute name in order to avoid naming conflicts in subclasses.

That is why you are able to reference ._Test__num and not .__num.  There's a StackOverflow question with more in-depth answers here:  Python name mangling

Title: Private properties in Python

Body:
I am very new to Python. Here is some test code:

class Test():
  def __init__(self,num,option):
    self.__num = num
    self.option = option
  def getNum(self):
    return self.__num
  def getOption(self):
     return self.option

my_num = Test(77,1)
print(my_num.getNum())    // 77
print(my_num._Test__num)  // 77
print(my_num.__num)       // Attribute error

My question is:

Why my_num.getNum() returns 77?

Why self.__num through getNum has value and my_num.__num returns error?

self in self.__num points to my_num, isn't it? Since __num is a private property, how is it accessible through self whereas self points to an object?


问:
Local Image not displayed in Skia.WPF Uno Platform project
I save images relative to the workingdirectory and then want to display them in a uno Skia.WPF app.

However they never appear.
This is how I create the ImageSource:

public static async Task<ImageSource> GenerateSource()
{
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.FileTypeFilter.Add(".png");
    var pickerResult = await picker.PickSingleFileAsync("tileset");
    if (pickerResult is null)
        return null;
    using var stream = await pickerResult.OpenReadAsync();

    string imagePath = Path.GetFullPath(Path.Combine("cache", "image.png"));
    Directory.CreateDirectory(Path.GetDirectoryName(imagePath));

    using (var bitmapImageStream = File.Open(imagePath,
                         FileMode.Create,
                         FileAccess.Write,
                         FileShare.None))
        {

            await stream.AsStreamForRead().CopyToAsync(bitmapImageStream);
            bitmapImageStream.Flush(true);
        }

    var imgSrc = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
    imgSrc.UriSource = new Uri($"file://{imagePath}");
    var width = imgSrc.PixelHeight;
    return imgSrc;
}
```
<p>But when I use the path directly in the Xaml it also not working.</p>
<pre class="lang-xml prettyprint-override"><code><Image Source="file://cache/image.png" Width="32" Height="32"  />
</code>```

Using an image from the Internet using an http url works.

Sample Repo

答: file: URIs are currently not supported in Uno, however, you can still show local images by copying to the appropriate folder using ms-appdata scheme. If you copy the file into ApplicationData.Current.TemporaryFolder, you will the be able to reference that path by ms-appdata:///temp/{imageName} URI.

Body:
I save images relative to the workingdirectory and then want to display them in a uno Skia.WPF app.

However they never appear.
This is how I create the ImageSource:

public static async Task<ImageSource> GenerateSource()
{
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.FileTypeFilter.Add(".png");
    var pickerResult = await picker.PickSingleFileAsync("tileset");
    if (pickerResult is null)
        return null;
    using var stream = await pickerResult.OpenReadAsync();

    string imagePath = Path.GetFullPath(Path.Combine("cache", "image.png"));
    Directory.CreateDirectory(Path.GetDirectoryName(imagePath));

    using (var bitmapImageStream = File.Open(imagePath,
                         FileMode.Create,
                         FileAccess.Write,
                         FileShare.None))
        {

            await stream.AsStreamForRead().CopyToAsync(bitmapImageStream);
            bitmapImageStream.Flush(true);
        }

    var imgSrc = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
    imgSrc.UriSource = new Uri($"file://{imagePath}");
    var width = imgSrc.PixelHeight;
    return imgSrc;
}

But when I use the path directly in the Xaml it also not working.

<Image Source="file://cache/image.png" Width="32" Height="32"  />

Using an image from the Internet using an http url works.

Sample Repo


问:
Jest testing, keeps return undefined?
I'm trying to test a function with jest, and I simply can figure out what's wrong? It keeps saying it expects to return the output, but got undefined. I have tested the function elsewhere where it seems to return the correct array.

I'm calling my my function and passing it an Object, it's then supposed to return an array. Then I'm calling  .toEqual(output) which is an array.

```<code>//This is my function
const allAddresses = [
];

const updateAllAddresses = (obj) => {
  const transferAmount = obj.transferAmount;
  const to = obj.to;
  const transferAddress = obj.address;
  const newBalance = obj.newBalance;
  const addressArr = [...allAddresses];
  console.log("This addressArr", addressArr);
  console.log("this is obj", obj);
  //To set your account to the new balance after transfer and
  //to check if the address you transfer to is your own account
  addressArr.map((address) => {
    if (address.account === transferAddress) {
      console.log("This is inside the map !!!!");
      address.balance = Number(newBalance);
    }
    if (address.account === to) {
      console.log("2");
      address.balance = Number(transferAmount) + Number(address.balance);
    }
    console.log("last part of the testing", addressArr);
    return addressArr;
  });
};

const obj = {
};
const output = [
];

//This is my test
describe("Update array", () => {
  test("update the array with the new information", () => {
    expect(updateAllAddresses(obj)).toEqual(output);
  });
});
</code>```

答:
There is a problem with your updateAllAddresses method.
You are not returning anything then the result of your function becomes undefined;

add return to where you are using .map method.

```<code>  return addressArr.map((address) => {
    if (address.account === transferAddress) {
      console.log("This is inside the map !!!!");
      address.balance = Number(newBalance);
    }
    if (address.account === to) {
      console.log("2");
      address.balance = Number(transferAmount) + Number(address.balance);
     }
    console.log("last part of the testing", addressArr);
    return address;
  });
</code>```

Title: Jest testing, keeps return undefined?

Body:
I'm trying to test a function with jest, and I simply can figure out what's wrong? It keeps saying it expects to return the output, but got undefined. I have tested the function elsewhere where it seems to return the correct array.

I'm calling my my function and passing it an Object, it's then supposed to return an array. Then I'm calling  .toEqual(output) which is an array.

//This is my function
const allAddresses = [
];

const updateAllAddresses = (obj) => {
  const transferAmount = obj.transferAmount;
  const to = obj.to;
  const transferAddress = obj.address;
  const newBalance = obj.newBalance;
  const addressArr = [...allAddresses];
  console.log("This addressArr", addressArr);
  console.log("this is obj", obj);
  //To set your account to the new balance after transfer and
  //to check if the address you transfer to is your own account
  addressArr.map((address) => {
    if (address.account === transferAddress) {
      console.log("This is inside the map !!!!");
      address.balance = Number(newBalance);
    }
    if (address.account === to) {
      console.log("2");
      address.balance = Number(transferAmount) + Number(address.balance);
    }
    console.log("last part of the testing", addressArr);
    return addressArr;
  });
};

const obj = {
};
const output = [
];

//This is my test
describe("Update array", () => {
  test("update the array with the new information", () => {
    expect(updateAllAddresses(obj)).toEqual(output);
  });
});

Body:
There is a problem with your updateAllAddresses method.
You are not returning anything then the result of your function becomes undefined;

add return to where you are using .map method.

  return addressArr.map((address) => {
    if (address.account === transferAddress) {
      console.log("This is inside the map !!!!");
      address.balance = Number(newBalance);
    }
    if (address.account === to) {
      console.log("2");
      address.balance = Number(transferAmount) + Number(address.balance);
     }
    console.log("last part of the testing", addressArr);
    return address;
  });


问:
Issues returning specific object from MongoDB Nested JSON Array
currently writing a flask api with python/pymongo.

Currently I am unable to return a specific object from this nested json array. I have been utilizing pymongo's db.collection.find(), and I either return the entire array or an empty set. Same thing happens in MongoDB  I will provide what I have tried below.

Sample of the JSON I am querying:

```<code>{
"elements": [
    {
        "type": "item",
        "id": 1,
        "geometry": {
            "type": "LineString",
            "coordinates": [

            ]
        },
        "tags": {
            "foot": "yes",
            "highway": "path",
            "mtb": "yes",
            "name": "Arch Cape to Cape Falcon Trail",
            "sac_scale": "hiking",
            "surface": "ground",
            "_osm_type": "way"
        }
    },
    {
        "type": "item",
        "id": 2,
        "geometry": {
            "type": "LineString",
            "coordinates": [

            ]
        },
        "tags": {
            "foot": "yes",
            "highway": "path",
            "mtb": "yes",
            "name": "Cape Falcon Trail",
            "sac_scale": "hiking",
            "surface": "ground",
            "_osm_type": "way"
        }
    }
]}
</code>```

I removed what was in coordinates for readability, due to it being thousands of lines long.

here is the python code. Note trailName does nothing here, as I have opted to test with individual IDs and names until I return the specific object I want.

```<code>@app.route('/<trailName>', methods = ['GET'])
def trail(trailName):
    try:
        # trails = db.output_data_retry.find({'elements.tags.name':"Arch Cape to Cape Falcon Trail"}) # returns entire collection
        # trails = db.output_data_retry.find_one({ "elements" : { "$elemMatch" : { "id":1 } } } ) # also just returns entire collection
        # trails = db.output_data_retry.aggregate({ "elements" : { "$elemMatch" : { "id":1 } } } ) # {"error": "pipeline must be a list"}
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } } ) # returns empty set
        # trails = db.output_data_retry.find({ "elements" : { "tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } }  } ) # empty set
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":"Arch%20Cape%20to%20Cape%20Falcon%20Trail" } } } ) # empty set
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":'Arch%20Cape%20to%20Cape%20Falcon%20Trail'} } } ) # empty set
        # trails = db.output_data_retry.find({ 'tags' : { "$elemMatch" : { 'name':"Arch Cape to Cape Falcon Trail" } } } ) # empty set
        # trails = db.output_data_retry.find({ "$match" : { "elements.tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } } } ) # empty set
        # trails = db.output_data_retry.find_one({'elements.tags.name':"Arch Cape to Cape Falcon Trail"}) # returns entire collection
        # trails = db.output_data_retry.find_one({'elements.tags.name':['Arch Cape to Cape Falcon Trail']}) #returns null
        # trails = db.output_data_retry.find_one({'elements.id':[1]}) #returns null
        trails = db.output_data_retry.find({'elements.id':[1]}) #returns an empty set
        return dumps(trails)
    except Exception as e:
       return dumps({'error' : str(e)})
</code>```

also note that the same thing happens in MongoDB compass when I attempt these queries. I eiether return the entire array, not the specific object attributes.

答:
try using:

return = list(users.find({}))

then tags = return("tags")

Body:
currently writing a flask api with python/pymongo.

Currently I am unable to return a specific object from this nested json array. I have been utilizing pymongo's db.collection.find(), and I either return the entire array or an empty set. Same thing happens in MongoDB  I will provide what I have tried below.

Sample of the JSON I am querying:

{
"elements": [
    {
        "type": "item",
        "id": 1,
        "geometry": {
            "type": "LineString",
            "coordinates": [

            ]
        },
        "tags": {
            "foot": "yes",
            "highway": "path",
            "mtb": "yes",
            "name": "Arch Cape to Cape Falcon Trail",
            "sac_scale": "hiking",
            "surface": "ground",
            "_osm_type": "way"
        }
    },
    {
        "type": "item",
        "id": 2,
        "geometry": {
            "type": "LineString",
            "coordinates": [

            ]
        },
        "tags": {
            "foot": "yes",
            "highway": "path",
            "mtb": "yes",
            "name": "Cape Falcon Trail",
            "sac_scale": "hiking",
            "surface": "ground",
            "_osm_type": "way"
        }
    }
]}

I removed what was in coordinates for readability, due to it being thousands of lines long.

here is the python code. Note trailName does nothing here, as I have opted to test with individual IDs and names until I return the specific object I want.

@app.route('/<trailName>', methods = ['GET'])
def trail(trailName):
    try:
        # trails = db.output_data_retry.find({'elements.tags.name':"Arch Cape to Cape Falcon Trail"}) # returns entire collection
        # trails = db.output_data_retry.find_one({ "elements" : { "$elemMatch" : { "id":1 } } } ) # also just returns entire collection
        # trails = db.output_data_retry.aggregate({ "elements" : { "$elemMatch" : { "id":1 } } } ) # {"error": "pipeline must be a list"}
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } } ) # returns empty set
        # trails = db.output_data_retry.find({ "elements" : { "tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } }  } ) # empty set
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":"Arch%20Cape%20to%20Cape%20Falcon%20Trail" } } } ) # empty set
        # trails = db.output_data_retry.find({ "elements.tags" : { "$elemMatch" : { "name":'Arch%20Cape%20to%20Cape%20Falcon%20Trail'} } } ) # empty set
        # trails = db.output_data_retry.find({ 'tags' : { "$elemMatch" : { 'name':"Arch Cape to Cape Falcon Trail" } } } ) # empty set
        # trails = db.output_data_retry.find({ "$match" : { "elements.tags" : { "$elemMatch" : { "name":"Arch Cape to Cape Falcon Trail" } } } } ) # empty set
        # trails = db.output_data_retry.find_one({'elements.tags.name':"Arch Cape to Cape Falcon Trail"}) # returns entire collection
        # trails = db.output_data_retry.find_one({'elements.tags.name':['Arch Cape to Cape Falcon Trail']}) #returns null
        # trails = db.output_data_retry.find_one({'elements.id':[1]}) #returns null
        trails = db.output_data_retry.find({'elements.id':[1]}) #returns an empty set
        return dumps(trails)
    except Exception as e:
       return dumps({'error' : str(e)})

also note that the same thing happens in MongoDB compass when I attempt these queries. I eiether return the entire array, not the specific object attributes.


问:
Spring Boot clear cache manually
I was following some online lesson's playlist, test project for spring boot. Simplie CRUD stuff. It created some tables, but i decided to change some fields names, dropped table from cmd connected to mysql. After the relaunch the project does not create this table once more. Am i right, that it's stored somewhere in cache, the record that the table has been already created? Or, for example, does it store the autoincrement id's value somewhere in cache? After the second relaunch spring just does not check the existence of the table in database because of some log in cache? How can i fix it without starting the project from scratch?</p>

答:
probably the spring.jpa.hibernate.ddl-auto is turn off or not set. try setting it to create-drop

here's a good reference
https://www.baeldung.com/spring-boot-data-sql-and-schema-sql

Title: Spring Boot clear cache manually


问:
VSC wrong java dependencies
I have a strange behaviour in Visual Studio Code, trying to debug a simple code with the VSC Debugger I have a runtime error, running the same code with Gradle the code works !

The problem is that running the code in VSC Debug mode the java code try to load two library, the commons-cli-1.2.jar and the new commons-cli-1.5.0.jar, in the old one some methods are not implemented and the code rise a java.lang.NoSuchMethodError

```<code>[144.386s][info][class,load] java.lang.Throwable$WrappedPrintStream source: jrt:/java.base
java.lang.NoSuchMethodError: 'boolean org.apache.commons.cli.Options.hasShortOption(java.lang.String)'
    at org.apache.commons.cli.DefaultParser.handleShortAndLongOption(DefaultParser.java:473)
    at org.apache.commons.cli.DefaultParser.handleToken(DefaultParser.java:542)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:712)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:679)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:660)
    at it.fox.dafne.App.main(App.java:38)
</code>```

The java code is:

  public static void main(String[] args) throws Exception {
    Options options = new Options();
    options.addOption("f", PROPERTY_FILE, true, "path to the properties file");
    try {
      var parser = new DefaultParser();
      CommandLine commandLine = parser.parse(options, args);
      String propertyFile = "";
      ...
      ...
```
<p>In the ClassPath there's no indication of the old library:</p>
<pre class="lang-xml prettyprint-override"><code>   <classpathentry  sourcepath="/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/e7e198ff537780c2835e484b0ffccd2960074504/commons-cli-1.5.0-sources.jar" kind="lib"  path="/Users/fox/.gradle/caches/modules-2/files-2.1/commons-   cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar">
</code>```

So, how is it possible for Java to find the Old version?

Visual Studio Code isn't supposed to use the java classPath which is in .classpath file ?

Enabling -verbose:class when the JVM is launched, the error is pretty clear:

```<code>[7.861s][info][class,load] org.apache.commons.cli.Options source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.862s][info][class,load] org.apache.commons.cli.Option source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.864s][info][class,load] org.apache.commons.cli.OptionValidator source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.867s][info][class,load] org.apache.commons.cli.CommandLineParser source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.867s][info][class,load] org.apache.commons.cli.DefaultParser source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar
[7.868s][info][class,load] org.apache.commons.cli.ParseException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.868s][info][class,load] org.apache.commons.cli.MissingArgumentException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.869s][info][class,load] org.apache.commons.cli.MissingOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.870s][info][class,load] org.apache.commons.cli.UnrecognizedOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.870s][info][class,load] org.apache.commons.cli.AmbiguousOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar
[7.871s][info][class,load] org.apache.commons.cli.CommandLine source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.872s][info][class,load] org.apache.commons.cli.Util source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
</code>```

In Gradle the dependencies are fine:

```<code>MacBook-Pro:plcProject fox$ gradle dafne:dependencies | grep commons-cli
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
+--- commons-cli:commons-cli:1.5.0 (n)
+--- commons-cli:commons-cli:1.5.0 (n)
|  +--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
|  +--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
</code>```

Gradle find some transitive dependencies but decide to use the newer version of the library and not the old one:

So the questions are:

VSC ClassPath is the Gradle one?

How could be possible that launching the code with Gradle is working and with VSC not ?

Thanks,

S.

答:
It seems that the code is fine.

The problem was solved cleaning up the Visual Studio Code cache where probably something was wrong.
To clear the cache you have to use the "Command Palette" (⇧⌘P, F1 on Mac; Ctrl+Shift+P, F1 on Windows) and use the command: "Java: Clean Java Server Language Workspace"

Title: VSC wrong java dependencies

Body:
I have a strange behaviour in Visual Studio Code, trying to debug a simple code with the VSC Debugger I have a runtime error, running the same code with Gradle the code works !

The problem is that running the code in VSC Debug mode the java code try to load two library, the commons-cli-1.2.jar and the new commons-cli-1.5.0.jar, in the old one some methods are not implemented and the code rise a java.lang.NoSuchMethodError

[144.386s][info][class,load] java.lang.Throwable$WrappedPrintStream source: jrt:/java.base
java.lang.NoSuchMethodError: 'boolean org.apache.commons.cli.Options.hasShortOption(java.lang.String)'
    at org.apache.commons.cli.DefaultParser.handleShortAndLongOption(DefaultParser.java:473)
    at org.apache.commons.cli.DefaultParser.handleToken(DefaultParser.java:542)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:712)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:679)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:660)
    at it.fox.dafne.App.main(App.java:38)

The java code is:

  public static void main(String[] args) throws Exception {
    Options options = new Options();
    options.addOption("f", PROPERTY_FILE, true, "path to the properties file");
    try {
      var parser = new DefaultParser();
      CommandLine commandLine = parser.parse(options, args);
      String propertyFile = "";
      ...
      ...

In the ClassPath there's no indication of the old library:

   <classpathentry  sourcepath="/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/e7e198ff537780c2835e484b0ffccd2960074504/commons-cli-1.5.0-sources.jar" kind="lib"  path="/Users/fox/.gradle/caches/modules-2/files-2.1/commons-   cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar">

So, how is it possible for Java to find the Old version?

Visual Studio Code isn't supposed to use the java classPath which is in .classpath file ?

Enabling -verbose:class when the JVM is launched, the error is pretty clear:

[7.861s][info][class,load] org.apache.commons.cli.Options source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.862s][info][class,load] org.apache.commons.cli.Option source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.864s][info][class,load] org.apache.commons.cli.OptionValidator source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.867s][info][class,load] org.apache.commons.cli.CommandLineParser source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.867s][info][class,load] org.apache.commons.cli.DefaultParser source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar
[7.868s][info][class,load] org.apache.commons.cli.ParseException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.868s][info][class,load] org.apache.commons.cli.MissingArgumentException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.869s][info][class,load] org.apache.commons.cli.MissingOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.870s][info][class,load] org.apache.commons.cli.UnrecognizedOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.870s][info][class,load] org.apache.commons.cli.AmbiguousOptionException source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.5.0/dc98be5d5390230684a092589d70ea76a147925c/commons-cli-1.5.0.jar
[7.871s][info][class,load] org.apache.commons.cli.CommandLine source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar
[7.872s][info][class,load] org.apache.commons.cli.Util source:  file:/Users/fox/.gradle/caches/modules-2/files-2.1/commons-cli/commons-cli/1.2/2bf96b7aa8b611c177d329452af1dc933e14501c/commons-cli-1.2.jar

In Gradle the dependencies are fine:

MacBook-Pro:plcProject fox$ gradle dafne:dependencies | grep commons-cli
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
+--- commons-cli:commons-cli:1.5.0 (n)
+--- commons-cli:commons-cli:1.5.0 (n)
|  +--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0
|  +--- commons-cli:commons-cli:1.5.0
|  |  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |  |  +--- commons-cli:commons-cli:1.2 -> 1.5.0
|  |  |  |     +--- commons-cli:commons-cli:1.2 -> 1.5.0
+--- commons-cli:commons-cli:1.5.0

Gradle find some transitive dependencies but decide to use the newer version of the library and not the old one:

So the questions are:

VSC ClassPath is the Gradle one?

How could be possible that launching the code with Gradle is working and with VSC not ?

Thanks,

S.


问:
Get Retrofit data. Android. Kotlin
I am new to programming and I need your help.
The task is this: I make a request from the service where I want to get the character's id, but it doesn't work. Below is the code!

Api

```<code>@GET("people/{id}")
    suspend fun getCharacter(@Path("id") id: Int): Response<Characters>
</code>```

Repository

```<code>suspend fun getCharacters(id: Int) =
        RetrofitBuilder.api.getCharacter(id)
</code>```

Viewmodel

```<code>class DetailViewModel : ViewModel() {
    var repository = StarWarsRepository()
    private val _response = MutableLiveData<Characters>()
    val character: LiveData<Characters>
        get() = _response

    fun getCharacter(id: Int) {
        viewModelScope.launch {
            repository.getCharacters(id).let { response ->

                if (response.isSuccessful) {
                    _response.postValue(response.body())
                } else {
                    Log.d("tag", "Error: ${response.code()}")
                }
            }
        }
    }
}
</code>```

Fragment
In line 27 I call the function
getCharacterViewModel()
and there you need to specify id. What do I need to specify in this parameter so that when I click on a character in the list, I have information about him?

```<code>
class DetailFragment : Fragment() {
    private var _binding: FragmentDetailBinding? = null
    private val binding get() = _binding!!
    private lateinit var viewModel: DetailViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentDetailBinding.inflate(inflater, container, false)
        val view = binding.root
        viewModel = ViewModelProvider(this)[(DetailViewModel::class.java)]
        getCharacterViewModel()
        return view
    }

    private fun getCharacterViewModel(id: Int){
        viewModel.getCharacter(id)
        viewModel.character.observe(this, { name ->
            binding.birth.text = name.birth_year
            binding.name.text = name.characters
            binding.mass.text = name.mass
            binding.mass.text = name.height

        })
    }

}
</code>```

答:
You want to click on an Item that's on one list and get info about the item, right?

You'll need to work on the list. Is it a RecyclerView? For example, if your list is a RecyclerView, you'll need to modify your adapter.

Create on more param on your adapter

```<code>class YourAdapter (..., val onItemClick: (Character) -> Unit){
   //Your Code Here
}
</code>```

And, on "onBind" method on your adapter, set the click listener on your view and call

```<code>onItemClick(<clickedItemHereAsParam>))
</code>```

within it.

Check this anwser with more details:
How do I implement onClickListener to a recyclerView to open a new fragment when clicked

Title: Get Retrofit data. Android. Kotlin

Body:
I am new to programming and I need your help.
The task is this: I make a request from the service where I want to get the character's id, but it doesn't work. Below is the code!

Api

@GET("people/{id}")
    suspend fun getCharacter(@Path("id") id: Int): Response<Characters>

Repository

suspend fun getCharacters(id: Int) =
        RetrofitBuilder.api.getCharacter(id)

Viewmodel

class DetailViewModel : ViewModel() {
    var repository = StarWarsRepository()
    private val _response = MutableLiveData<Characters>()
    val character: LiveData<Characters>
        get() = _response

    fun getCharacter(id: Int) {
        viewModelScope.launch {
            repository.getCharacters(id).let { response ->

                if (response.isSuccessful) {
                    _response.postValue(response.body())
                } else {
                    Log.d("tag", "Error: ${response.code()}")
                }
            }
        }
    }
}

Fragment
In line 27 I call the function
getCharacterViewModel()
and there you need to specify id. What do I need to specify in this parameter so that when I click on a character in the list, I have information about him?

class DetailFragment : Fragment() {
    private var _binding: FragmentDetailBinding? = null
    private val binding get() = _binding!!
    private lateinit var viewModel: DetailViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentDetailBinding.inflate(inflater, container, false)
        val view = binding.root
        viewModel = ViewModelProvider(this)[(DetailViewModel::class.java)]
        getCharacterViewModel()
        return view
    }

    private fun getCharacterViewModel(id: Int){
        viewModel.getCharacter(id)
        viewModel.character.observe(this, { name ->
            binding.birth.text = name.birth_year
            binding.name.text = name.characters
            binding.mass.text = name.mass
            binding.mass.text = name.height

        })
    }

}

Body:
You want to click on an Item that's on one list and get info about the item, right?

You'll need to work on the list. Is it a RecyclerView? For example, if your list is a RecyclerView, you'll need to modify your adapter.

Create on more param on your adapter

class YourAdapter (..., val onItemClick: (Character) -> Unit){
   //Your Code Here
}

And, on "onBind" method on your adapter, set the click listener on your view and call

onItemClick(<clickedItemHereAsParam>))

within it.

Check this anwser with more details:
How do I implement onClickListener to a recyclerView to open a new fragment when clicked