问:
Is it safe to delete keys from Redis while iterating through them using scan?
I want to iterate through a number of keys that are stored in Redis with the same prefix using scan and do some processing in my app code with the key's values. Is it safe to delete the keys returned from scan's output after processing them? I don't see this mentioned in the scan documentation: https://redis.io/commands/scan</p>

答:
Yes, it's safe to delete the returned keys.

Redis scan is stateless. Keyspace change (e.g. adding new keys or removing old keys) during the scan process does not make the scan fail, although Keyspace change might lead to keys missing or duplicated keys returned.

Check this on the details of how Redis scan work.


来源: stackexchange

问:
Auto cleanup of inactive sessions in DolphinDB
I am wondering if there is any method I can set the inactive sessions to be automatically cleaned up after a period of time. Is there any way to achieve this? Thanks!</p>

答:
Currently, there isn't a way to set it directly because some inactive sessions may be active again after a period of time. However, you can use a user-defined function to call a scheduled job. An exaple is shown following:</p>
```<code>def closeNotActiveSessions() {
    gap = 43200000 \\ 12:00:00.000
    sessionIds = exec sessionId from pnodeRun(getSessionMemorytStat) where now() - lastActiveTime > gap
    closeSessions(sessionIds)
}
scheduleJob(jobId = `daily, jobDesc = "Daily Job 1", jobFunc = closeNotActiveSessions, scheduleTime = 10:00m, startDate = 2022.01.01, endDate = 2022.12.31, frequency = 'D')
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Currently, there isn't a way to set it directly because some inactive sessions may be active again after a period of time. However, you can use a user-defined function to call a scheduled job. An exaple is shown following:

def closeNotActiveSessions() {
    gap = 43200000 \\ 12:00:00.000
    sessionIds = exec sessionId from pnodeRun(getSessionMemorytStat) where now() - lastActiveTime > gap
    closeSessions(sessionIds)
}
scheduleJob(jobId = `daily, jobDesc = "Daily Job 1", jobFunc = closeNotActiveSessions, scheduleTime = 10:00m, startDate = 2022.01.01, endDate = 2022.12.31, frequency = 'D')


问:
How to change text color of Short Description PHP Code that I applied on Woocommerce Checkout?
Used template: Hello Elementor

I applied PHP code in Functions.php and it works great. However I want to be able to customize color of Short Description that appeared thanks to the PHP code I found on StackOverFlow.

```<code>// add this filter in functions.php file
add_filter( 'woocommerce_get_item_data', 'wc_checkout_description_so_15127954', 10, 2 );
function wc_checkout_description_so_15127954( $other_data, $cart_item )
{
    $post_data = get_post( $cart_item['product_id'] );
$other_data[] = array(
  'key' => 'Details',
  'display' =>  $post_data->post_excerpt );
    return $other_data;
}
</code>```

Image

Details: [ETH] Random

Is example of the text I want color to be changed

答:
Please try this:</p>
```<code>// add this filter in functions.php file
add_filter( 'woocommerce_get_item_data', 'wc_checkout_description_so_15127954', 10, 2 );
function wc_checkout_description_so_15127954( $other_data, $cart_item )
{
$post_data = get_post( $cart_item['product_id'] );
$description = '<span style="color:red">'.$post_data->post_excerpt.'</span>';
$other_data[] = array(
'key' => 'Details',
'display' =>  $description );
return $other_data;
}
</code>```

Body:
Used template: Hello Elementor

I applied PHP code in Functions.php and it works great. However I want to be able to customize color of Short Description that appeared thanks to the PHP code I found on StackOverFlow.

// add this filter in functions.php file
add_filter( 'woocommerce_get_item_data', 'wc_checkout_description_so_15127954', 10, 2 );
function wc_checkout_description_so_15127954( $other_data, $cart_item )
{
    $post_data = get_post( $cart_item['product_id'] );
$other_data[] = array(
  'key' => 'Details',
  'display' =>  $post_data->post_excerpt );
    return $other_data;
}

Image

Details: [ETH] Random

Is example of the text I want color to be changed

Body:
Please try this:

// add this filter in functions.php file
add_filter( 'woocommerce_get_item_data', 'wc_checkout_description_so_15127954', 10, 2 );
function wc_checkout_description_so_15127954( $other_data, $cart_item )
{
$post_data = get_post( $cart_item['product_id'] );
$description = '<span style="color:red">'.$post_data->post_excerpt.'</span>';
$other_data[] = array(
'key' => 'Details',
'display' =>  $description );
return $other_data;
}


问:
how to have 2 different messages depending on user input using using the while function?
i created a code that solves mathematic problems by the user. The problems have to involve addition, subtraction, division or multiplication.  the code runs without any errors but the issue is I want the code to give two distinct messages for the user.

when the user runs the code for the first time "Please enter the problem in this format (number1 operator number2) or type 'stop' to exist"

when the user enters the problem in the wrong format "invalid enter please try again with the right format or enter 'stop' to exist'

while True:
    while True:
        problem = input("Please enter the problem in this format (number1 operator number2) or type 'stop' to exist: ").split()
        if problem[0] == 'stop':
            break
        if len(problem) != 3:
            continue
        n1,op,n2 = problem
        if any( not (n.isnumeric() or n.count('.')==1 and n.replace('.','').isnumeric()) for n in (n1,n2) ):
            continue
        if op not in ('+','-','*','/','//','**'):
        #this is the tuple of operators which tell the computer which operature the user is using
            continue
        break
    if problem[0] == 'stop':
        break
    match op:
        case '+': result = float(n1)+float(n2)
        case '-': result = float(n1)-float(n2)
        case '*': result = float(n1)*float(n2)
        case '**': result = float(n1)**float(n2)
        case '/': result = float(n1)/float(n2)
            #this will give a float answer. Ex: 1 / 9 = 0.11
        case '//': result = float(n1)//float(n2)
            #this will give an integer answer. Ex: 1 / 9 = 0
    print(f'{result:,.2f}')

```

答:
an improved version of your code

```<code>print("Please enter the problem in this format (number1 operator number2) or type 'stop' to exist: ")
while True:
    problem = input("").split()
    operators = ['+','-','*','/','//','**']

    if problem[0] == 'stop':
        break
    if len(problem) != 3:
        print('invalid entry please try again with the right format or enter stop to exist')
    else:
        if (problem[0].isdigit() == True) and(problem[1] in operators) and (problem[2].isdigit() == True):

            n1 = float(problem[0])
            n2 = float(problem[2])

            if problem[1] == '+':
                result = n1 + n2
            elif problem[1] == '-':
                result = n1 - n2
            elif problem[1] == '*':
                result =  n1 * n2
            elif problem[1] == '**':
                result = n1**n2
            elif problem[1] == '/':
                result = n1/n2
            elif problem[1] == '//':
                result = n1//n2

            print('\n', result, '\n')
        else:
            print('invalid entry please try again with the right format or enter stop to exist')
</code>```

Output

```<code>Please enter the problem in this format (number1 operator number2) or type 'stop' to exist:
4

invalid entry please try again with the right format or enter stop to exist
4 + 1

5.0

stop #exit the program
</code>```

Body:
an improved version of your code

print("Please enter the problem in this format (number1 operator number2) or type 'stop' to exist: ")
while True:
    problem = input("").split()
    operators = ['+','-','*','/','//','**']

    if problem[0] == 'stop':
        break
    if len(problem) != 3:
        print('invalid entry please try again with the right format or enter stop to exist')
    else:
        if (problem[0].isdigit() == True) and(problem[1] in operators) and (problem[2].isdigit() == True):

            n1 = float(problem[0])
            n2 = float(problem[2])

            if problem[1] == '+':
                result = n1 + n2
            elif problem[1] == '-':
                result = n1 - n2
            elif problem[1] == '*':
                result =  n1 * n2
            elif problem[1] == '**':
                result = n1**n2
            elif problem[1] == '/':
                result = n1/n2
            elif problem[1] == '//':
                result = n1//n2

            print('\n', result, '\n')
        else:
            print('invalid entry please try again with the right format or enter stop to exist')

Output

Please enter the problem in this format (number1 operator number2) or type 'stop' to exist:
4

invalid entry please try again with the right format or enter stop to exist
4 + 1

5.0

stop #exit the program


问:
can i stop peoples from pressing space to change to the next slide in powerpoint
I am working on a PowerPoint game, and I need to stop people from skipping to the next slide by all means. I currently disabled the navigation bar and the clicking, but when I disable the navigation bar (look in the video), the animation for my spinning bar doesn't start automatically.

video: https://drive.google.com/file/d/1E1RCVmOd54ZKgAE4xBrtCatrtunHhVBb/view?usp=sharing

答:
Simply use Setup Slide Show in slide show panel.

then, use browse at kiosk.
The arrows should Disappear.
(I didn't use this, because it would prevent me from using other features of my game.)


问:
How do I return a list with newly added objects from a method (Beginner) C#
I am having trouble returning a list from a method called "omvandlaBetyg" which translates to "convert grades". I have added a total of 5 'char' to my list. I wish to return the list from the method.

With many attempts I have not been able to solve this issue.
I am sorry for having set the names of the lists/variables to another language.

If it is too difficult to try and find a solution for my issue then I will translate it as soon as possible.

Thanks in advance.

```<code>    static void Main(string[] args)
    {
        string[] ämnen = { "Matematik", "Svenska", "Engelska", "Historia", "Fysik" };
        int[] poäng = new int[5];
        List<char> betyg = new List<char>(); // This is the list that is currently empty

        Program.LäsPoäng(poäng);

        Program.omvandlaBetyg(poäng, betyg);

        Program.skrivUtBetyg(betyg, ämnen);

    }
    static int LäsPoäng(int[] poäng)
    {
        Console.Write("Ange totalpoäng för matematik:");
        int matPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för svenska:");
        int svePoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för engelska:");
        int engPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för historia:");
        int hisPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för fysik:");
        int fysPoäng = Convert.ToInt32(Console.ReadLine());

        poäng[0] = matPoäng;
        poäng[1] = svePoäng;
        poäng[2] = engPoäng;
        poäng[3] = hisPoäng;
        poäng[4] = fysPoäng;

        return poäng[4];
    }
    static char omvandlaBetyg(int[] poäng, List <char> betyg)
    {

        foreach (int i in poäng)
        {
            if (i < 50)
            {
                betyg.Add('F');
            }
            else if (i >= 50 && i < 60)
            {
                betyg.Add('E');
            }
            else if (i > 60 && i < 75)
            {
                betyg.Add('D');
            }
            else if (i > 75 && i < 90)
            {
                betyg.Add('C');
            }
            else if (i > 90 && i < 100)
            {
                betyg.Add('B');
            }
            else if (i == 100)
            {
                betyg.Add('A');
            }
        }
        return betyg; // This is the list that has been updated with newly added char's
                      // that i wish to return from this method
    }
    static void skrivUtBetyg(List<char> betyg, string[] ämnen)
    {
        foreach (char item in betyg)
        {
             Console.WriteLine("Betyg i : " + item );
        }
    }
    static void Statistik()
    {

    }

}
</code>```

}

答:
I'm assuming you're trying to learn C#, but there are a few odd things in your code; here's what it could look like:

```<code>static void Main(string[] args)
{
    var ämnen = new string[] { "Matematik", "Svenska", "Engelska", "Historia", "Fysik" };

    // No need to create your lists/arrays here and pass them to these methods
    // as they can return them directly

    var poäng = LäsPoäng(ämnen);
    var betyg = OmvandlaBetyg(poäng);
    SkrivUtBetyg(betyg);
}

// The purpose of that method is to query grades and return them
static List<int> LäsPoäng(string[] ämnen)
{
    // Create your list here, and return it when you've asked all grades
    var poäng = new List<int>();

    // Redundant code, you've got a list of subjects so you might as well use them
    // This means you could add new subjects without changing this method
    foreach (var str in ämnen)
    {
        Console.Write($"Ange totalpoäng för {str.ToLower()}:");
        poäng.Add(Convert.ToInt32(Console.ReadLine()));
    }

    return poäng;
}

// The purpose of that method is to convert integer grades to A-F
// Method name should use camel case
static List<char> OmvandlaBetyg(List<int> poäng)
{
    // Create your list here, and return it when you've converted all grades
    var betyg = new List<char>();

    foreach (int i in poäng)
    {
        if (i < 50)
            betyg.Add('F');
        else if (i < 60) // No need to check lower bound, previous "if" takes care of it
            betyg.Add('E');
        else if (i < 75)
            betyg.Add('D');
        else if (i < 90)
            betyg.Add('C');
        else if (i < 100)
            betyg.Add('B');
        else
            betyg.Add('A');
    }

    return betyg;
}

// Camel case
static void SkrivUtBetyg(List<char> betyg)
{
    foreach (char item in betyg)
    {
        Console.WriteLine($"Betyg i : {item}");
    }
}
</code>```

It could still be improved and is by no means perfect, but hopefully it will give you some pointers.

Body:
I am having trouble returning a list from a method called "omvandlaBetyg" which translates to "convert grades". I have added a total of 5 'char' to my list. I wish to return the list from the method.

With many attempts I have not been able to solve this issue.
I am sorry for having set the names of the lists/variables to another language.

If it is too difficult to try and find a solution for my issue then I will translate it as soon as possible.

Thanks in advance.

    static void Main(string[] args)
    {
        string[] ämnen = { "Matematik", "Svenska", "Engelska", "Historia", "Fysik" };
        int[] poäng = new int[5];
        List<char> betyg = new List<char>(); // This is the list that is currently empty

        Program.LäsPoäng(poäng);

        Program.omvandlaBetyg(poäng, betyg);

        Program.skrivUtBetyg(betyg, ämnen);

    }
    static int LäsPoäng(int[] poäng)
    {
        Console.Write("Ange totalpoäng för matematik:");
        int matPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för svenska:");
        int svePoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för engelska:");
        int engPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för historia:");
        int hisPoäng = Convert.ToInt32(Console.ReadLine());

        Console.Write("Ange totalpoäng för fysik:");
        int fysPoäng = Convert.ToInt32(Console.ReadLine());

        poäng[0] = matPoäng;
        poäng[1] = svePoäng;
        poäng[2] = engPoäng;
        poäng[3] = hisPoäng;
        poäng[4] = fysPoäng;

        return poäng[4];
    }
    static char omvandlaBetyg(int[] poäng, List <char> betyg)
    {

        foreach (int i in poäng)
        {
            if (i < 50)
            {
                betyg.Add('F');
            }
            else if (i >= 50 && i < 60)
            {
                betyg.Add('E');
            }
            else if (i > 60 && i < 75)
            {
                betyg.Add('D');
            }
            else if (i > 75 && i < 90)
            {
                betyg.Add('C');
            }
            else if (i > 90 && i < 100)
            {
                betyg.Add('B');
            }
            else if (i == 100)
            {
                betyg.Add('A');
            }
        }
        return betyg; // This is the list that has been updated with newly added char's
                      // that i wish to return from this method
    }
    static void skrivUtBetyg(List<char> betyg, string[] ämnen)
    {
        foreach (char item in betyg)
        {
             Console.WriteLine("Betyg i : " + item );
        }
    }
    static void Statistik()
    {

    }

}

}

Body:
I'm assuming you're trying to learn C#, but there are a few odd things in your code; here's what it could look like:

static void Main(string[] args)
{
    var ämnen = new string[] { "Matematik", "Svenska", "Engelska", "Historia", "Fysik" };

    // No need to create your lists/arrays here and pass them to these methods
    // as they can return them directly

    var poäng = LäsPoäng(ämnen);
    var betyg = OmvandlaBetyg(poäng);
    SkrivUtBetyg(betyg);
}

// The purpose of that method is to query grades and return them
static List<int> LäsPoäng(string[] ämnen)
{
    // Create your list here, and return it when you've asked all grades
    var poäng = new List<int>();

    // Redundant code, you've got a list of subjects so you might as well use them
    // This means you could add new subjects without changing this method
    foreach (var str in ämnen)
    {
        Console.Write($"Ange totalpoäng för {str.ToLower()}:");
        poäng.Add(Convert.ToInt32(Console.ReadLine()));
    }

    return poäng;
}

// The purpose of that method is to convert integer grades to A-F
// Method name should use camel case
static List<char> OmvandlaBetyg(List<int> poäng)
{
    // Create your list here, and return it when you've converted all grades
    var betyg = new List<char>();

    foreach (int i in poäng)
    {
        if (i < 50)
            betyg.Add('F');
        else if (i < 60) // No need to check lower bound, previous "if" takes care of it
            betyg.Add('E');
        else if (i < 75)
            betyg.Add('D');
        else if (i < 90)
            betyg.Add('C');
        else if (i < 100)
            betyg.Add('B');
        else
            betyg.Add('A');
    }

    return betyg;
}

// Camel case
static void SkrivUtBetyg(List<char> betyg)
{
    foreach (char item in betyg)
    {
        Console.WriteLine($"Betyg i : {item}");
    }
}

It could still be improved and is by no means perfect, but hopefully it will give you some pointers.


问:
How to switch elements in data.frame according to size?
I am looking for an R function that allows swapping two elements in a data frame under a certain constraint.

For example:

If I have a dataframe (5rows, 5cols) and I want that all elements in column 2 that are greater than the corresponding elements in column 3 to be swapped. As a result, all the elements of column 2 greater than those of column 3 would move to column 3 and vice-versa.

Your help is much appreciated.

Body:
You can use swap from seqinr :

x = as.data.frame(matrix(sample(1:25), nrow = 5))
x
#>   V1 V2 V3 V4 V5
#> 1  1  7 22  6 10
#> 2  9 17 16 13  2
#> 3 23 19 12 24 20
#> 4  3 14 15  5 25
#> 5 18  8 11 21  4
ind <- (x[2] > x[3])
seqinr::swap(x[ind, 2], x[ind, 3])
x
#>   V1 V2 V3 V4 V5
#> 1  1  7 22  6 10
#> 2  9 16 17 13  2
#> 3 23 12 19 24 20
#> 4  3 14 15  5 25
#> 5 18  8 11 21  4


问:
Retrofit2 Authorization - Global Interceptor for access token
I'm trying to use Retrofit2,
I want to add Token to my Header Like this:

Authorization: Bearer  Token
but the code below doesn't work:

```<code>public interface APIService {
    @Headers({"Authorization", "Bearer "+ token})
    @GET("api/Profiles/GetProfile?id={id}")
    Call<UserProfile> getUser(@Path("id") String id);
}
</code>```

My server is asp.net webApi. Please help what should I do?

答:
The best approach is to use the new Authenticator API.

```<code>class TokenAuthenticator : Authenticator {
    override fun authenticate(route: Route?, response: Response): Request? {
        if (response.request.header("Authorization") != null) {
            return null
        }
        return response.request.newBuilder().header("Authorization", "Bearer " + token).build()
    }
}
OkHttpClient.Builder().authenticator(TokenAuthenticator()).build()
</code>```

Reference: https://square.github.io/okhttp/recipes/#handling-authentication-kt-java

Body:
I'm trying to use Retrofit2,
I want to add Token to my Header Like this:

Authorization: Bearer  Token
but the code below doesn't work:

public interface APIService {
    @Headers({"Authorization", "Bearer "+ token})
    @GET("api/Profiles/GetProfile?id={id}")
    Call<UserProfile> getUser(@Path("id") String id);
}

My server is asp.net webApi. Please help what should I do?

Body:
The best approach is to use the new Authenticator API.

class TokenAuthenticator : Authenticator {
    override fun authenticate(route: Route?, response: Response): Request? {
        if (response.request.header("Authorization") != null) {
            return null
        }
        return response.request.newBuilder().header("Authorization", "Bearer " + token).build()
    }
}
OkHttpClient.Builder().authenticator(TokenAuthenticator()).build()

Reference: https://square.github.io/okhttp/recipes/#handling-authentication-kt-java


问:
DATE(timestamp_expression[, timezone]) in Bigquery: convert UTC (2021-12-07T04:46:16Z) to local time, UTC has T and Z in SQL. How to get AEST?
I am first removing T, Z. then converting to TIMESTAMP and converting to AEST.

```<code>SELECT firstSignUpDate_rev,
TIMESTAMP(SAFE_CAST(PARSE_DATETIME('%Y-%m-%d %H:%M:%S', firstSignUpDate_rev)as DATETIME), 'Australia/Sydney')
FROM
(SELECT firstSignUpDate,
REGEXP_REPLACE(firstSignUpDate, 'T|Z', ' ') as firstSignUpDate_rev
FROM xxxxxxx.xxxx
</code>```

But the results are not correct . It should have added 11 hrs to the previous UTC time. Which is not correct as can be seen in the result,
Bigquery results

答:
the correct way is to

TIMESTAMP(SAFE_CAST(PARSE_DATETIME('%Y-%m-%dT%H:%M:%SZ', firstSignUpDate)as DATETIME))

Stripping T and Z is not the right way. It should be changed to TIMESTAMP format.

Finally, get the result with 10 hours being added to UTC

2021-09-16 00:36:30 UTC
2021-09-16T10:36:30

Body:
I am first removing T, Z. then converting to TIMESTAMP and converting to AEST.

SELECT firstSignUpDate_rev,
TIMESTAMP(SAFE_CAST(PARSE_DATETIME('%Y-%m-%d %H:%M:%S', firstSignUpDate_rev)as DATETIME), 'Australia/Sydney')
FROM
(SELECT firstSignUpDate,
REGEXP_REPLACE(firstSignUpDate, 'T|Z', ' ') as firstSignUpDate_rev
FROM xxxxxxx.xxxx

But the results are not correct . It should have added 11 hrs to the previous UTC time. Which is not correct as can be seen in the result,
Bigquery results


问:
Moment.js formatting date field to a day earlier than it should
This is a very small little bug I'm trying to fix in my code. I have a React component with this initial state

```<code>const initialFormData = Object.freeze({
    date: Moment(new Date()).format('YYYY-MM-DD'),
    price_per_gallon: '',
    trip_distance: '',
    gallons: '',
    car: ''
});

const [formData, updateFormData] = useState(initialFormData);
</code>```

Which is used in a form like so:

```<code><MuiPickersUtilsProvider utils={DateFnsUtils}>
    <Grid container justifyContent="space-around">
        <KeyboardDatePicker
            fullWidth
            disableToolbar
            inputVariant="outlined"
            format="yyyy-MM-dd"
            margin="normal"
            id="date-picker-inline"
            label="Date of Fillup"
            name="date"
            value={formData.date}
            onChange={handleDateChange}
            KeyboardButtonProps={{
                'aria-label': 'change date',
        }}
        />
    </Grid>
</MuiPickersUtilsProvider>
</code>```

I've done console.logs to see that the Moment(new Date()).format('YYYY-MM-DD') shows today's date, as I want, but for some reason when the component renders it has the default date in the field as yesterday, but if I were to get rid of initializing the date with the Moment instance and just have it be 'new Date()', it renders with today's date correctly.

Any idea why this could be? Kind of wracking my brain here, I just want the default date on my form to be whatever the current day is, and need to format it to YYYY-MM-DD because that's how my API sends and receives the data

Edit: Here are three console.logs I've tried:

```<code>console.log(new Date());
console.log(Moment(new Date()).format('YYYY-MM-DD'));
console.log(Moment().format('YYYY-MM-DD'));
</code>```

and their results:

```<code>Wed Feb 09 2022 22:01:41 GMT-0500 (Eastern Standard Time)
2022-02-09
2022-02-09
</code>```

But for some reason the second two using Moment will cause the component to render with yesterday's date

答:
First, you can emove the plain JS new Date() as agument to moment.

```<code>date: moment().format('YYYY-MM-DD')
</code>```

No argument is necesssary to moment to have a moment object for local time. It's the default ;)

Then, as mentionned in comments by Vengleab SO, you are passing that date to KeyboardDatePicker which (most probably) assumes that is a UTC date and "removes" your time offset from it. That would explain why the date is yesterday when testing it between 19H00 and midnight (your local GMT-5 time).

So... Just passing a time along the date should fix the issue.

```<code>date: moment().format('YYYY-MM-DD 12:00:00')
</code>```

Body:
This is a very small little bug I'm trying to fix in my code. I have a React component with this initial state

const initialFormData = Object.freeze({
    date: Moment(new Date()).format('YYYY-MM-DD'),
    price_per_gallon: '',
    trip_distance: '',
    gallons: '',
    car: ''
});

const [formData, updateFormData] = useState(initialFormData);

Which is used in a form like so:

<MuiPickersUtilsProvider utils={DateFnsUtils}>
    <Grid container justifyContent="space-around">
        <KeyboardDatePicker
            fullWidth
            disableToolbar
            inputVariant="outlined"
            format="yyyy-MM-dd"
            margin="normal"
            id="date-picker-inline"
            label="Date of Fillup"
            name="date"
            value={formData.date}
            onChange={handleDateChange}
            KeyboardButtonProps={{
                'aria-label': 'change date',
        }}
        />
    </Grid>
</MuiPickersUtilsProvider>

I've done console.logs to see that the Moment(new Date()).format('YYYY-MM-DD') shows today's date, as I want, but for some reason when the component renders it has the default date in the field as yesterday, but if I were to get rid of initializing the date with the Moment instance and just have it be 'new Date()', it renders with today's date correctly.

Any idea why this could be? Kind of wracking my brain here, I just want the default date on my form to be whatever the current day is, and need to format it to YYYY-MM-DD because that's how my API sends and receives the data

Edit: Here are three console.logs I've tried:

console.log(new Date());
console.log(Moment(new Date()).format('YYYY-MM-DD'));
console.log(Moment().format('YYYY-MM-DD'));

and their results:

Wed Feb 09 2022 22:01:41 GMT-0500 (Eastern Standard Time)
2022-02-09
2022-02-09

But for some reason the second two using Moment will cause the component to render with yesterday's date

Body:
First, you can emove the plain JS new Date() as agument to moment.

date: moment().format('YYYY-MM-DD')

No argument is necesssary to moment to have a moment object for local time. It's the default ;)

Then, as mentionned in comments by Vengleab SO, you are passing that date to KeyboardDatePicker which (most probably) assumes that is a UTC date and "removes" your time offset from it. That would explain why the date is yesterday when testing it between 19H00 and midnight (your local GMT-5 time).

So... Just passing a time along the date should fix the issue.

date: moment().format('YYYY-MM-DD 12:00:00')


问:
Creating Fully-Transparent Shapes in Electron BrowserWindow (A "Cut-Out" Window)?
I'd like to create a browserWindow that has a cutout (or hole) in it.

I'm looking to create something similar to this:

Essentially, it is a window that contains a fully-transparent shape inside of it, while the rest of the entire application remains unaffected.
I've heard of some ways of doing this using the Win32 API in applications programmed in C# or C++ using SetWindowRgn. Is this also possible in Electron?

Here is a code snippet of a tutorial I found online in C++ demonstrating what I'm looking to do in Electron:

```<code>void CHolesDlg::CreateHole(CRgn& rgn)
{
    CRgn WindowRgn;
    CRgn HoleRgn;
    static CRgn ThisRgn;

    CRect WindowRect;
    static bool Start = true;
    GetWindowRect (WindowRect);   // Get the Window rect
    WindowRgn.CreateRectRgn (0,0,WindowRect.Width (), WindowRect.Height());

    // initialize the hole region
    HoleRgn.CreateRectRgn (0,0,0,0);

    if (Start)
    {
       // initialize ThisRgn
       ThisRgn.CreateRectRgn (0,0,0,0);
       // First copy the region himself in ThisRgn
       ThisRgn.CopyRgn (&rgn);
    }
    else
    {
       // Other times, Add the new region to ThisRgn
       ThisRgn.CombineRgn (&ThisRgn, &rgn, RGN_OR);
    }

    Start = false;
    // create the border of the hole(s) with ThisRgn and set it in that
    // border by reversing it
    HoleRgn.CombineRgn (&ThisRgn, &WindowRgn, RGN_XOR);
    SetWindowRgn ((HRGN__*)HoleRgn.m_hObject, TRUE);
}

void CMyControl::ClearHoles()
{
    CRect WindowRect;
    CRgn WindowRgn;
    GetWindowRect (WindowRect);
    WindowRgn.CreateRectRgn (0,0,WindowRect.Width (), WindowRect.Height());
    // Get back to the classic border
    SetWindowRgn ((HRGN__*)WindowRgn.m_hObject, TRUE);
}

void CMyControl::OnClear()
{
    // TODO: Add your control notification handler code here
    CString s;
    GetDlgItem (IDC_CLEAR)->GetWindowText (s);
    if (s == "Clear Holes")
    {
       GetDlgItem (IDC_CLEAR)->SetWindowText ("Show Holes");
       ClearHoles();
    }

    if (s == "Show Holes")
    {
       GetDlgItem (IDC_CLEAR)->SetWindowText ("Clear Holes");
       ShowHoles();
    }
}
</code>```

Does anybody know how to do this? I am using Electron with NodeJS.

Many thanks for any suggestions or replies in advance.

EDIT [2/10/2022]: I am not looking to create the entire browserWindow transparent, only a small portion of it, while the rest of the window remains unaffected (see above image as an example of what I am looking for).

答:
Last time I checked, it was not normally possible. Your best bet would be to create a transparent, frameless window but the transparent area would still not be clickable.

However, there does seem to be a trick with triggering mouse events to sort of emulate click-through transparency. I am not sure how well it works in different operating systems though but you can go ahead and check the GitHub issue here, where it's been discussed.

I myself did not read it in detail, just went through it quickly before posting my answer.

As for making your window transparent, it's as simple as this:

```<code>const { BrowserWindow } = require('electron');

let win = new BrowserWindow({
    width: 800,
    height: 600,
    transparent: true,
    frame: false
});

win.show();
</code>```

Body:
I'd like to create a browserWindow that has a cutout (or hole) in it.

I'm looking to create something similar to this:

Essentially, it is a window that contains a fully-transparent shape inside of it, while the rest of the entire application remains unaffected.
I've heard of some ways of doing this using the Win32 API in applications programmed in C# or C++ using SetWindowRgn. Is this also possible in Electron?

Here is a code snippet of a tutorial I found online in C++ demonstrating what I'm looking to do in Electron:

void CHolesDlg::CreateHole(CRgn& rgn)
{
    CRgn WindowRgn;
    CRgn HoleRgn;
    static CRgn ThisRgn;

    CRect WindowRect;
    static bool Start = true;
    GetWindowRect (WindowRect);   // Get the Window rect
    WindowRgn.CreateRectRgn (0,0,WindowRect.Width (), WindowRect.Height());

    // initialize the hole region
    HoleRgn.CreateRectRgn (0,0,0,0);

    if (Start)
    {
       // initialize ThisRgn
       ThisRgn.CreateRectRgn (0,0,0,0);
       // First copy the region himself in ThisRgn
       ThisRgn.CopyRgn (&rgn);
    }
    else
    {
       // Other times, Add the new region to ThisRgn
       ThisRgn.CombineRgn (&ThisRgn, &rgn, RGN_OR);
    }

    Start = false;
    // create the border of the hole(s) with ThisRgn and set it in that
    // border by reversing it
    HoleRgn.CombineRgn (&ThisRgn, &WindowRgn, RGN_XOR);
    SetWindowRgn ((HRGN__*)HoleRgn.m_hObject, TRUE);
}

void CMyControl::ClearHoles()
{
    CRect WindowRect;
    CRgn WindowRgn;
    GetWindowRect (WindowRect);
    WindowRgn.CreateRectRgn (0,0,WindowRect.Width (), WindowRect.Height());
    // Get back to the classic border
    SetWindowRgn ((HRGN__*)WindowRgn.m_hObject, TRUE);
}

void CMyControl::OnClear()
{
    // TODO: Add your control notification handler code here
    CString s;
    GetDlgItem (IDC_CLEAR)->GetWindowText (s);
    if (s == "Clear Holes")
    {
       GetDlgItem (IDC_CLEAR)->SetWindowText ("Show Holes");
       ClearHoles();
    }

    if (s == "Show Holes")
    {
       GetDlgItem (IDC_CLEAR)->SetWindowText ("Clear Holes");
       ShowHoles();
    }
}

Does anybody know how to do this? I am using Electron with NodeJS.

Many thanks for any suggestions or replies in advance.

EDIT [2/10/2022]: I am not looking to create the entire browserWindow transparent, only a small portion of it, while the rest of the window remains unaffected (see above image as an example of what I am looking for).

Body:
Last time I checked, it was not normally possible. Your best bet would be to create a transparent, frameless window but the transparent area would still not be clickable.

However, there does seem to be a trick with triggering mouse events to sort of emulate click-through transparency. I am not sure how well it works in different operating systems though but you can go ahead and check the GitHub issue here, where it's been discussed.

I myself did not read it in detail, just went through it quickly before posting my answer.

As for making your window transparent, it's as simple as this:

const { BrowserWindow } = require('electron');

let win = new BrowserWindow({
    width: 800,
    height: 600,
    transparent: true,
    frame: false
});

win.show();


问:
CSV does not load to Google BigQuery
So I made a program that'll get the schema from a table in a MySQL Server, create a table based on the said schema, and insert the data rows which are saved in a  CSV file in a Google Cloud Storage.

Code for getting the schema from MySQL:

foreach (string table in listOfTableNames)
   {
      MySqlCommand query = new MySqlCommand($"desc {table}", openedMySQLConnection);
      MySqlDataReader reader = query.ExecuteReader();

      DataTable dt = new DataTable(table);
      dt.Load(reader);
      reader.Close();
      object[][] result = dt.AsEnumerable().Select(x => x.ItemArray).ToArray();
      TableSchemas.Add(table, result);
   }
```
<hr />
<p>Google BigQuery table maker from schema looped per table:</p>
<pre class="lang-cs prettyprint-override"><code>var schemaBuilder = new TableSchemaBuilder();
foreach (var column in dictionaryOfSchemas[myTablename])
{
   string columnType = column[1].ToString().ToLower();
   schemaBuilder.Add(
      column[0].ToString(),
      columnType.Contains("varchar") ? BigQueryDbType.String :
         (columnType.Contains("int") ? BigQueryDbType.Int64 :
         (columnType.Contains("decimal") ? BigQueryDbType.Float64 :
         (columnType.Contains("timestamp") ? BigQueryDbType.DateTime :
         (columnType.Contains("datetime") ? BigQueryDbType.DateTime :
         (columnType.Contains("date") ? BigQueryDbType.Date :
         BigQueryDbType.String)))))
   );
}
TableSchema schema = schemaBuilder.Build();
BigQueryTable newTable = bigquery.GetDataset(myDataset).CreateTable(myTablename, schema);
</code>```

CSV to created GBQ table looped per table:

    bigquery.CreateLoadJob(
       $"gs://{myProjectIdString}/{myBucketNameString}/{myCSVFilename}",
       newTable.Reference,
       schema,
       new CreateLoadJobOptions()
       {
           SourceFormat = FileFormat.Csv,
           SkipLeadingRows = 1
       }
    ).PollUntilCompleted();
```

No error shows up after running the CreateLoadJob method.

Schema of the new table seems to be good and matches the CSV and the MySQL table:

Here's a sneak peak into the CSV file in Cloud Storage with some data redacted out:

But there's still no data in the table:

Am I doing something wrong? I'm still learning Google services so any help and insight would be appreciated. :)

答:
After fiddling with my variables and links, I figured out that making a link to your bucket folder should be gs://<bucket_name>/<csv_filename> instead of gs://<project_id>/<bucket_name>/<csv_filename>.
My code's running ok for now and successfully transferred data.

Title: CSV does not load to Google BigQuery

Body:
So I made a program that'll get the schema from a table in a MySQL Server, create a table based on the said schema, and insert the data rows which are saved in a  CSV file in a Google Cloud Storage.

Code for getting the schema from MySQL:

foreach (string table in listOfTableNames)
   {
      MySqlCommand query = new MySqlCommand($"desc {table}", openedMySQLConnection);
      MySqlDataReader reader = query.ExecuteReader();

      DataTable dt = new DataTable(table);
      dt.Load(reader);
      reader.Close();
      object[][] result = dt.AsEnumerable().Select(x => x.ItemArray).ToArray();
      TableSchemas.Add(table, result);
   }

Google BigQuery table maker from schema looped per table:

var schemaBuilder = new TableSchemaBuilder();
foreach (var column in dictionaryOfSchemas[myTablename])
{
   string columnType = column[1].ToString().ToLower();
   schemaBuilder.Add(
      column[0].ToString(),
      columnType.Contains("varchar") ? BigQueryDbType.String :
         (columnType.Contains("int") ? BigQueryDbType.Int64 :
         (columnType.Contains("decimal") ? BigQueryDbType.Float64 :
         (columnType.Contains("timestamp") ? BigQueryDbType.DateTime :
         (columnType.Contains("datetime") ? BigQueryDbType.DateTime :
         (columnType.Contains("date") ? BigQueryDbType.Date :
         BigQueryDbType.String)))))
   );
}
TableSchema schema = schemaBuilder.Build();
BigQueryTable newTable = bigquery.GetDataset(myDataset).CreateTable(myTablename, schema);

CSV to created GBQ table looped per table:

    bigquery.CreateLoadJob(
       $"gs://{myProjectIdString}/{myBucketNameString}/{myCSVFilename}",
       newTable.Reference,
       schema,
       new CreateLoadJobOptions()
       {
           SourceFormat = FileFormat.Csv,
           SkipLeadingRows = 1
       }
    ).PollUntilCompleted();

No error shows up after running the CreateLoadJob method.

Schema of the new table seems to be good and matches the CSV and the MySQL table:

Here's a sneak peak into the CSV file in Cloud Storage with some data redacted out:

But there's still no data in the table:

Am I doing something wrong? I'm still learning Google services so any help and insight would be appreciated. :)


问:
Conditional classes in Vue using objects inside v-for loop
I am using v-for to iterate over an array of objects inside my data. For each object I have in the array, I want a link. Each link should have their own class dependent on the Boolean hide property in their object.

But when I try to pass an object property into the class via :class="{ game.hide: hideGame }", Vue outputs an error:
Parsing error: Unexpected Token .

What am I doing wrong?

```<code><template>
  <div class="showcase-container">
    <button :class="{ leftArrow: noGames }">test</button>
    <a
      v-for="game in games"
      :key="game.id"
      :class="{ game.hide: hideGame }"
      href="#"
      >{{ game.name }}</a
    >
    <button>test</button>
  </div>
</template>

<script>
export default {
  noGames: true,
  data() {
    return {
      games: [
        {
          name: "Game 1",
          link: "https://google.com",
          id: 1,
          hide: false,
        },
        {
          name: "Game 2",
          link: "https://youtube.com",
          id: 2,
          hide: true,
        },
      ],
      noGames: true,
    };
  },
  methods: {
    showGame() {
      alert(this.game1);
    },
  },
};
</script>

<style lang="scss">
.leftArrow {
  visibility: hidden;
}
.hideGame {
  display: none;
}
</style>
</code>```

答:
Minor note:

Your two CSS class names “game.hide” should be written “game hide” without the dot “.”

So Brahim string should look like

```<code>:class="{'game hide':hideGame  }"
</code>```

Body:
I am using v-for to iterate over an array of objects inside my data. For each object I have in the array, I want a link. Each link should have their own class dependent on the Boolean hide property in their object.

But when I try to pass an object property into the class via :class="{ game.hide: hideGame }", Vue outputs an error:
Parsing error: Unexpected Token .

What am I doing wrong?

<template>

    <button :class="{ leftArrow: noGames }">test</button>
    {{ game.name }}
    <button>test</button>

</template>

Body:
Minor note:

Your two CSS class names “game.hide” should be written “game hide” without the dot “.”

So Brahim string should look like

:class="{'game hide':hideGame  }"


问:
How to call a function inside another function in VBA?
I'm trying to call a function inside another function but the result I'm getting is 0

```<code>Function DepositRate(Deposit):
    If Deposit > 100000 Then
        Rtaxa = 0.078
    ElseIf Deposit <= 100000 And Deposit > 10000 Then
        Rtaxa = 0.073
    ElseIf Deposit <= 10000 And Deposit > 1000 Then
        Rtaxa = 0.063
    ElseIf Deposit <= 1000 And Deposit > 0 Then
        Rtaxa = 0.055
    Else
        Rtaxa = "Negative Value"
    End If

    DepositRate = Rtaxa

End Function

Function NewDFV(Value, Year):
    Call DepositRate(Value)
    ValorFuturo = Deposit * (1 + Rtaxa) ^ (Year)
    NewDFV = ValorFuturo

End Function
</code>```

So,  Where I'm doing wrong here ?

答:
A Function Calling a Function

Note that both functions can be used as UDF's. If you don't want the first function to appear in the functions list, use Private Function GetDepositrate(...)... while keeping both functions in the same module. The function will still be available just not listed.

Option Explicit

Function GetDepositrate(ByVal Deposit As Double) As Double

    Dim RTaxa As Double

    If Deposit > 100000 Then
        RTaxa = 0.078
    ElseIf Deposit > 10000 Then
        RTaxa = 0.073
    ElseIf Deposit > 1000 Then
        RTaxa = 0.063
    ElseIf Deposit > 0 Then
        RTaxa = 0.055
    Else
        ' Negative Value - do nothing
    End If

    GetDepositrate = RTaxa

End Function

Function NewDFV(ByVal Deposit As Double, ByVal Year As Long) As Double

    Dim RTaxa As Double: RTaxa = GetDepositrate(Deposit)

    NewDFV = Deposit * (1 + RTaxa) ^ (Year)

End Function
```

Body:
I'm trying to call a function inside another function but the result I'm getting is 0

Function DepositRate(Deposit):
    If Deposit > 100000 Then
        Rtaxa = 0.078
    ElseIf Deposit <= 100000 And Deposit > 10000 Then
        Rtaxa = 0.073
    ElseIf Deposit <= 10000 And Deposit > 1000 Then
        Rtaxa = 0.063
    ElseIf Deposit <= 1000 And Deposit > 0 Then
        Rtaxa = 0.055
    Else
        Rtaxa = "Negative Value"
    End If

    DepositRate = Rtaxa

End Function

Function NewDFV(Value, Year):
    Call DepositRate(Value)
    ValorFuturo = Deposit * (1 + Rtaxa) ^ (Year)
    NewDFV = ValorFuturo

End Function

So,  Where I'm doing wrong here ?


问:
Linux: who is listening on tcp port 22?
I have a AST2600 evb board. After power on (w/ RJ45 connected), it boots into a OpenBMC kernel. From serial port, using ip command I can obtain its IP address. From my laptop, I can ssh into the board using account root/0penBmc:

```<code>bruin@gen81:/$ ssh root@192.168.6.132
root@192.168.6.132's password:
</code>```

Then I want to find out which tcp ports are open. As there is no ss/lsof/netstat utilities, I cat /proc/net/tcp:

```<code>root@AMIfa7ba648f62e:/proc/net# cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:14EB 00000000:0000 0A 00000000:00000000 00:00000000 00000000   997        0 9565 1 0c202562 100 0 0 10 0
   1: 3500007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000   997        0 9571 1 963c8114 100 0 0 10 0
</code>```

The strange thing puzzled me is that that tcp port 22 is not listed in /proc/net/tcp, which suggests that no process is listening on tcp port 22. If this is true, how the ssh connection is established?

Btw, as tested using ps, it's the dropbear process who is handling the ssh connection, and the dropbear is spawned dynamically (i.e., if no ssh connection, no such process exist; if I made two ssh connection, two dropbear processes were spawned).

PS: as suggested by John in his reply, I added the ss utilities into the image, and it shows what I expected:

```<code>root@AMI8287361b9c6f:~# ss -antp
State            Recv-Q            Send-Q                                  Local Address:Port                                  Peer Address:Port
LISTEN           0                 0                                             0.0.0.0:5355                                       0.0.0.0:*                 users:(("systemd-resolve",pid=239,fd=12))
LISTEN           0                 0                                           127.0.0.1:5900                                       0.0.0.0:*                 users:(("obmc-ikvm",pid=314,fd=5))
LISTEN           0                 0                                          127.0.0.53:53                                         0.0.0.0:*                 users:(("systemd-resolve",pid=239,fd=17))
LISTEN           0                 0                                                   *:443                                              *:*                 users:(("bmcweb",pid=325,fd=3),("systemd",pid=1,fd=41))
LISTEN           0                 0                                                   *:5355                                             *:*                 users:(("systemd-resolve",pid=239,fd=14))
LISTEN           0                 0                                                   *:5900                                             *:*                 users:(("obmc-ikvm",pid=314,fd=6))
LISTEN           0                 0                                                   *:22                                               *:*                 users:(("systemd",pid=1,fd=49))
LISTEN           0                 0                                                   *:2200                                             *:*                 users:(("systemd",pid=1,fd=50))
ESTAB            0                 0                               [::ffff:192.168.6.89]:22                           [::ffff:192.168.6.98]:34906             users:(("dropbear",pid=485,fd=2),("dropbear",pid=485,fd=1),("dropbear",pid=485,fd=0),("systemd",pid=1,fd=20))
</code>```

答:
Good question.

First, it is pretty straigt forward to add common tools/utitlies to an image.
It could be added (for local testing only) by adding a line

```<code>OBMC_IMAGE_EXTRA_INSTALL:append = " iproute2 iproute2-ss"
</code>```

to the https://github.com/openbmc/openbmc/blob/master/meta-aspeed/conf/machine/evb-ast2600.conf file (or to your own testing/deveopment layer). Adding useful tools is often worth it.

Second, if you are using ipv6 you will need to check /proc/net/tcp6

Third, you can also look for a port by looking up the pid of your application ps | grep <application name>. Then reading the port used by that pid cat /proc/<pid>/net/tcp

Last, if you have any more question or these steps don't work. Please reach out to us on discord https://discord.com/invite/69Km47zH98 or Email https://lists.ozlabs.org/listinfo/openbmc (they are the preferred place to ask questions)

Title: Linux: who is listening on tcp port 22?

Body:
I have a AST2600 evb board. After power on (w/ RJ45 connected), it boots into a OpenBMC kernel. From serial port, using ip command I can obtain its IP address. From my laptop, I can ssh into the board using account root/0penBmc:

bruin@gen81:/$ ssh root@192.168.6.132
root@192.168.6.132's password:

Then I want to find out which tcp ports are open. As there is no ss/lsof/netstat utilities, I cat /proc/net/tcp:

root@AMIfa7ba648f62e:/proc/net# cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:14EB 00000000:0000 0A 00000000:00000000 00:00000000 00000000   997        0 9565 1 0c202562 100 0 0 10 0
   1: 3500007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000   997        0 9571 1 963c8114 100 0 0 10 0

The strange thing puzzled me is that that tcp port 22 is not listed in /proc/net/tcp, which suggests that no process is listening on tcp port 22. If this is true, how the ssh connection is established?

Btw, as tested using ps, it's the dropbear process who is handling the ssh connection, and the dropbear is spawned dynamically (i.e., if no ssh connection, no such process exist; if I made two ssh connection, two dropbear processes were spawned).

PS: as suggested by John in his reply, I added the ss utilities into the image, and it shows what I expected:

root@AMI8287361b9c6f:~# ss -antp
State            Recv-Q            Send-Q                                  Local Address:Port                                  Peer Address:Port
LISTEN           0                 0                                             0.0.0.0:5355                                       0.0.0.0:*                 users:(("systemd-resolve",pid=239,fd=12))
LISTEN           0                 0                                           127.0.0.1:5900                                       0.0.0.0:*                 users:(("obmc-ikvm",pid=314,fd=5))
LISTEN           0                 0                                          127.0.0.53:53                                         0.0.0.0:*                 users:(("systemd-resolve",pid=239,fd=17))
LISTEN           0                 0                                                   *:443                                              *:*                 users:(("bmcweb",pid=325,fd=3),("systemd",pid=1,fd=41))
LISTEN           0                 0                                                   *:5355                                             *:*                 users:(("systemd-resolve",pid=239,fd=14))
LISTEN           0                 0                                                   *:5900                                             *:*                 users:(("obmc-ikvm",pid=314,fd=6))
LISTEN           0                 0                                                   *:22                                               *:*                 users:(("systemd",pid=1,fd=49))
LISTEN           0                 0                                                   *:2200                                             *:*                 users:(("systemd",pid=1,fd=50))
ESTAB            0                 0                               [::ffff:192.168.6.89]:22                           [::ffff:192.168.6.98]:34906             users:(("dropbear",pid=485,fd=2),("dropbear",pid=485,fd=1),("dropbear",pid=485,fd=0),("systemd",pid=1,fd=20))

Body:
Good question.

First, it is pretty straigt forward to add common tools/utitlies to an image.
It could be added (for local testing only) by adding a line

OBMC_IMAGE_EXTRA_INSTALL:append = " iproute2 iproute2-ss"

to the https://github.com/openbmc/openbmc/blob/master/meta-aspeed/conf/machine/evb-ast2600.conf file (or to your own testing/deveopment layer). Adding useful tools is often worth it.

Second, if you are using ipv6 you will need to check /proc/net/tcp6

Third, you can also look for a port by looking up the pid of your application ps | grep <application name>. Then reading the port used by that pid cat /proc/<pid>/net/tcp

Last, if you have any more question or these steps don't work. Please reach out to us on discord https://discord.com/invite/69Km47zH98 or Email https://lists.ozlabs.org/listinfo/openbmc (they are the preferred place to ask questions)


问:
Runtime Code Coverage Tools
I know that there are a number of tools for analysing .NET code and calculating the coverage, plus identifying classes/methods/properties etc that are never going to be hit.

However, I am trying to clean-up a legacy application that I am certain contains an amount of unused code - however a lot of code is accessed via some arbitrary and complex reflection tecniques that will disguise the intent to the compiler - thererfore any coverage tool that only analyses the compiled code is unlikely to generate any reliable reports on code useage within this application.

Are there any tools that work rather like profilers, whereby they listen to a running application and log what classes/methods/properties are actually hit and generate the coverage based on this data.

I hope Ive made everything clear - thanks in anticipation

答:
we are using ncover, and it works really nicely: http://www.ncover.com/.
But it's commerical, or you use the trial version, if you just need it once.</p>

ContentLicense: CC BY-SA 3.0

Title: Runtime Code Coverage Tools


问:
Can someone explain to me what's the proper usage of gRPC StreamObserver.onError?
I am trying to handle gRPC errors properly (Java, Spring-boot app).

Basically, I need too transfer error details from gRPC server to client, but I find it hard to understand the proper usage of StreamObserver.onError();

The method doc says:

"Receives a terminating error from the stream. May only be called once
and if called it must be the last method called. In particular if an
exception is thrown by an implementation of onError no further calls
to any method are allowed."

What does this "no further calls are allowed" mean? In the app that I maintain, they call other gRPC methods and they get java.lang.IllegalStateException: call already closed which is just fine, as per documentation.

I am wondering - should I (the developer) terminate the current java method (which usus gRPC calls) after an error is received? Like for example throwing an exception to stop execution. Or it is expected tht gRPC is going to terminate the execution.. (something like throwing an exception from gRPC)

Basically how do I properly use onError() and what should I expect and handle if I call it?
I need an explanation of its usage and effects.

答:
I've extracted a template for GRPC streaming which sort of abstracts away a lot of the GRPC boilerplate that also addresses the the logic for onError.  In the DechunkingStreamObserver

I use the following general pattern for GRPC streaming which is something along the lines of

```<code>META DATA DATA DATA META DATA DATA DATA
</code>```

An example of where I would use it would be to take one form and transform it to another form.

message SavedFormMeta {
  string id = 1;
}

message SavedFormChunk {
  oneof type {
    SavedFormMeta meta = 1;
    bytes data = 2;
  }
}

rpc saveFormDataStream(stream SavedFormChunk) returns (stream SavedFormChunk) {}
```
<p>I use a flag that would track the <code>inError</code> state to prevent further processing and catch exceptions on the <code>onNext</code> and <code>onComplete</code> both of which I redirect to <code>onError</code> which forwards the error to the server side.</p>
<p>The code below pulls the GRPC semantics and takes lamdas that do the processing.</p>
```
/**
 * Dechunks a GRPC stream from the request and calls the consumer when a complete object is created.  This stops
 * further processing once an error has occurred.
 *
 * @param <T> entity type
 * @param <R> GRPC chunk message type
 * @param <S> GRPC message type for response streams
 */
class DechunkingStreamObserver<T, R, S> implements StreamObserver<R> {

    /**
     * This function takes the current entity state and the chunk and returns a copy of the combined result.  Note the combiner may modify the existing data, but may cause unexpected behaviour.
     */
    private final BiFunction<T, R, T> combiner;

    /**
     * A function that takes in the assembled object and the GRPC response observer.
     */
    private final BiConsumer<T, StreamObserver<S>> consumer;

    /**
     * Predicate that returns true if it is a meta chunk indicating a start of a new object.
     */
    private final Predicate<R> metaPredicate;

    /**
     * this function gets the meta chunk and supplies a new object.
     */
    private final Function<R, T> objectSupplier;

    /**
     * GRPC response observer.
     */
    private final StreamObserver<S> responseObserver;

    /**
     * Currently being processed entity.
     */
    private T current = null;

    /**
     * In error state.  Starts {@code false}, but once it is set to {@code true} it stops processing {@link #onNext(Object)}.
     */
    private boolean inError = false;

    /**
     * @param metaPredicate    predicate that returns true if it is a meta chunk indicating a start of a new object.
     * @param objectSupplier   this function gets the meta chunk and supplies a new object
     * @param combiner         this function takes the current entity state and the chunk and returns a copy of the combined result.  Note the combiner may modify the existing data, but may cause unexpected behaviour.
     * @param consumer         a function that takes in the assembled object and the GRPC response observer.
     * @param responseObserver GRPC response observer
     */
    DechunkingStreamObserver(
            final Predicate<R> metaPredicate,
            final Function<R, T> objectSupplier,
            final BiFunction<T, R, T> combiner,
            final BiConsumer<T, StreamObserver<S>> consumer,
            final StreamObserver<S> responseObserver) {

        this.metaPredicate = metaPredicate;
        this.objectSupplier = objectSupplier;
        this.combiner = combiner;
        this.consumer = consumer;
        this.responseObserver = responseObserver;
    }

    @Override
    public void onCompleted() {

        if (inError) {
            return;
        }
        try {
            if (current != null) {
                consumer.accept(current, responseObserver);
            }
            responseObserver.onCompleted();
        } catch (final Exception e) {
            onError(e);
        }

    }

    @Override
    public void onError(final Throwable throwable) {

        responseObserver.onError(throwable);
        inError = true;

    }

    @Override
    public void onNext(final R chunk) {

        if (inError) {
            return;
        }
        try {
            if (metaPredicate.test(chunk)) {
                if (current != null) {
                    consumer.accept(current, responseObserver);
                }
                current = objectSupplier.apply(chunk);
            } else {
                current = combiner.apply(current, chunk);
            }
        } catch (final Exception e) {
            onError(e);
        }
    }
}
```

I have 4 lamdas

Predicate<R> metaPredicate which takes in a chunk and returns whether the chunk is meta or not.

Function<R, T> objectSupplier which takes in a meta chunk and creates a new object that is used by your module.

BiFunction<T, R, T> combiner, which takes in a data chunk and the current object and returns a new object that contains the combination.

BiConsumer<T, StreamObserver<S>> consumer which will consume a completed object.  It also passes in a stream observer in the case of sending new objects in response.

Body:
I've extracted a template for GRPC streaming which sort of abstracts away a lot of the GRPC boilerplate that also addresses the the logic for onError.  In the DechunkingStreamObserver

I use the following general pattern for GRPC streaming which is something along the lines of

META DATA DATA DATA META DATA DATA DATA

An example of where I would use it would be to take one form and transform it to another form.

message SavedFormMeta {
  string id = 1;
}

message SavedFormChunk {
  oneof type {
    SavedFormMeta meta = 1;
    bytes data = 2;
  }
}

rpc saveFormDataStream(stream SavedFormChunk) returns (stream SavedFormChunk) {}

I use a flag that would track the inError state to prevent further processing and catch exceptions on the onNext and onComplete both of which I redirect to onError which forwards the error to the server side.

The code below pulls the GRPC semantics and takes lamdas that do the processing.

/**
 * Dechunks a GRPC stream from the request and calls the consumer when a complete object is created.  This stops
 * further processing once an error has occurred.
 *
 * @param <T> entity type
 * @param <R> GRPC chunk message type
 * @param <S> GRPC message type for response streams
 */
class DechunkingStreamObserver<T, R, S> implements StreamObserver<R> {

    /**
     * This function takes the current entity state and the chunk and returns a copy of the combined result.  Note the combiner may modify the existing data, but may cause unexpected behaviour.
     */
    private final BiFunction<T, R, T> combiner;

    /**
     * A function that takes in the assembled object and the GRPC response observer.
     */
    private final BiConsumer<T, StreamObserver<S>> consumer;

    /**
     * Predicate that returns true if it is a meta chunk indicating a start of a new object.
     */
    private final Predicate<R> metaPredicate;

    /**
     * this function gets the meta chunk and supplies a new object.
     */
    private final Function<R, T> objectSupplier;

    /**
     * GRPC response observer.
     */
    private final StreamObserver<S> responseObserver;

    /**
     * Currently being processed entity.
     */
    private T current = null;

    /**
     * In error state.  Starts {@code false}, but once it is set to {@code true} it stops processing {@link #onNext(Object)}.
     */
    private boolean inError = false;

    /**
     * @param metaPredicate    predicate that returns true if it is a meta chunk indicating a start of a new object.
     * @param objectSupplier   this function gets the meta chunk and supplies a new object
     * @param combiner         this function takes the current entity state and the chunk and returns a copy of the combined result.  Note the combiner may modify the existing data, but may cause unexpected behaviour.
     * @param consumer         a function that takes in the assembled object and the GRPC response observer.
     * @param responseObserver GRPC response observer
     */
    DechunkingStreamObserver(
            final Predicate<R> metaPredicate,
            final Function<R, T> objectSupplier,
            final BiFunction<T, R, T> combiner,
            final BiConsumer<T, StreamObserver<S>> consumer,
            final StreamObserver<S> responseObserver) {

        this.metaPredicate = metaPredicate;
        this.objectSupplier = objectSupplier;
        this.combiner = combiner;
        this.consumer = consumer;
        this.responseObserver = responseObserver;
    }

    @Override
    public void onCompleted() {

        if (inError) {
            return;
        }
        try {
            if (current != null) {
                consumer.accept(current, responseObserver);
            }
            responseObserver.onCompleted();
        } catch (final Exception e) {
            onError(e);
        }

    }

    @Override
    public void onError(final Throwable throwable) {

        responseObserver.onError(throwable);
        inError = true;

    }

    @Override
    public void onNext(final R chunk) {

        if (inError) {
            return;
        }
        try {
            if (metaPredicate.test(chunk)) {
                if (current != null) {
                    consumer.accept(current, responseObserver);
                }
                current = objectSupplier.apply(chunk);
            } else {
                current = combiner.apply(current, chunk);
            }
        } catch (final Exception e) {
            onError(e);
        }
    }
}

I have 4 lamdas

Predicate<R> metaPredicate which takes in a chunk and returns whether the chunk is meta or not.

Function<R, T> objectSupplier which takes in a meta chunk and creates a new object that is used by your module.

BiFunction<T, R, T> combiner, which takes in a data chunk and the current object and returns a new object that contains the combination.

BiConsumer<T, StreamObserver<S>> consumer which will consume a completed object.  It also passes in a stream observer in the case of sending new objects in response.


问:
Extracting layer output from Classification model of SimpleTransformer
I have fine tuned a bert base model for text classification task. Now, I want to extract hidden layer output so as to combine this output with other features to train a random forest model.
Problem lies in the fact that I don't know how to extract hidden layer output. It would be really great if someone can help me out in this regard.</p>
```<code>from simpletransformers.classification import ClassificationModel

model_xlm = ClassificationModel('bert', 'bert-base-uncased')
model_xlm.train_model(df_train)
</code>```

答:
Ran across this in a Google search, and recently saw the answer to this by reading the source code in the SimpleTransformers git repo.

To get the hidden layer output, just pass output_hidden_states in to the model:

```<code>model_xlm = ClassificationModel('bert', 'bert-base-uncased', {"output_hidden_states": True})
</code>```

then when you call predict, you will get this:

```<code>preds, model_outputs, all_embedding_outputs, all_layer_hidden_states = model.predict(data)
</code>```

Here is the reference in the source:
https://github.com/ThilinaRajapakse/simpletransformers/blob/68f0faace15530fa1a738a34ea13521eec4518b1/simpletransformers/classification/classification_model.py#L2242

Body:
I have fine tuned a bert base model for text classification task. Now, I want to extract hidden layer output so as to combine this output with other features to train a random forest model.
Problem lies in the fact that I don't know how to extract hidden layer output. It would be really great if someone can help me out in this regard.

from simpletransformers.classification import ClassificationModel

model_xlm = ClassificationModel('bert', 'bert-base-uncased')
model_xlm.train_model(df_train)

Body:
Ran across this in a Google search, and recently saw the answer to this by reading the source code in the SimpleTransformers git repo.

To get the hidden layer output, just pass output_hidden_states in to the model:

model_xlm = ClassificationModel('bert', 'bert-base-uncased', {"output_hidden_states": True})

then when you call predict, you will get this:

preds, model_outputs, all_embedding_outputs, all_layer_hidden_states = model.predict(data)

Here is the reference in the source:
https://github.com/ThilinaRajapakse/simpletransformers/blob/68f0faace15530fa1a738a34ea13521eec4518b1/simpletransformers/classification/classification_model.py#L2242


问:
Mimic a descriptor with a function
I am trying to mimic a descriptor with a decorator function, but have failed. Here's what I have tried.

```<code>def my_property(self):
    def wrapper(func):
        return func(self)
    return wrapper

class C:
    def __init__(self):
        self._x = 0

    @my_property(C()) # this will print 0 for me, but it's not from the obj `c`
    def p(self):
        return self._x

c = C()
print(c.p)
</code>```

Overriding __get__ directly in the decorator didn't help me either. I also tried to inherit the function class and override its __get__ method, but was told function is final and not subclassable (probably I should try forbiddenfruit https://github.com/clarete/forbiddenfruit).

Can anyone help?

Edit: To clarify, I was wondering if it is possible without having to use the keyword class?

答:
Your intuition is right to override __get__. In fact, that's exactly how properties in Python actually work.

Consider

```<code>class MyProperty:

    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return self.func(instance)
</code>```

MyProperty is a class whose instances contain a func. When we __get__ an instance of MyProperty off a class, it'll call the inner function automatically.

Now we'll make a neat wrapper function for it. Pretty trivial, but still nice to be consistent with Python's nomenclature for functions vs. types

```<code>def my_property(func):
    return MyProperty(func)
</code>```

Finally, using the decorator.

```<code>class C:
    def __init__(self):
        self._x = 0

    @my_property
    def p(self):
        return self._x

c = C()
print(c.p) # Prints 0
</code>```

Title: Mimic a descriptor with a function

Body:
I am trying to mimic a descriptor with a decorator function, but have failed. Here's what I have tried.

def my_property(self):
    def wrapper(func):
        return func(self)
    return wrapper

class C:
    def __init__(self):
        self._x = 0

    @my_property(C()) # this will print 0 for me, but it's not from the obj `c`
    def p(self):
        return self._x

c = C()
print(c.p)

Overriding __get__ directly in the decorator didn't help me either. I also tried to inherit the function class and override its __get__ method, but was told function is final and not subclassable (probably I should try forbiddenfruit https://github.com/clarete/forbiddenfruit).

Can anyone help?

Edit: To clarify, I was wondering if it is possible without having to use the keyword class?

Body:
Your intuition is right to override __get__. In fact, that's exactly how properties in Python actually work.

Consider

class MyProperty:

    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return self.func(instance)

MyProperty is a class whose instances contain a func. When we __get__ an instance of MyProperty off a class, it'll call the inner function automatically.

Now we'll make a neat wrapper function for it. Pretty trivial, but still nice to be consistent with Python's nomenclature for functions vs. types

def my_property(func):
    return MyProperty(func)

Finally, using the decorator.

class C:
    def __init__(self):
        self._x = 0

    @my_property
    def p(self):
        return self._x

c = C()
print(c.p) # Prints 0


问:
Xamarin Forms BLE Plugin Scan Issue Android 12
I have written a xamarin forms app which uses the Plugin.BLE NuGet package to scan and connect to ble devices. It was working/debugging flawlessly on my phone until it(my phone) updated to Android 12.0 - API 31. I am using the basic vanilla implementation from the plugin:

```<code>adapter.DeviceDiscovered += (s,a) => deviceList.Add(a.Device);
await adapter.StartScanningForDevicesAsync();
</code>```

I have found that Android 12 requires different runtime permissions ([https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower][1]) and I have tried to accomodate them in the manifest file:

```<code>    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
    <application android:label="Rep_001.Android" android:theme="@style/MainTheme"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower
</code>```

but alas I am having no luck. I am thinking that I need to ask the user for scan and connect privileges at runtime but I am not sure how to do that as Xamarin.Essentials does not have bluetooth permissions requests.

答:
Well, I figured it out. Within the Android Project, I created a class that inherits from Xamarin.Essentials.Permissions.BasePlatformPermission:

```<code> public class BLEPermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
    (Android.Manifest.Permission.BluetoothScan, true),
    (Android.Manifest.Permission.BluetoothConnect, true)
}.ToArray();
}
</code>```

Then within MainActivity.cs -> OnCreate() I inserted the RequestAsync immediately after the Application is loaded:

```<code>        protected override async void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());

        await Permissions.RequestAsync<BLEPermission>();
    }
</code>```

Now when the app loads for the first time it asks the user for bluetooth scanning an connecting permissions. All subsequent launches do not re-prompt for permissions.
Sites/Documentation that helped along the way

https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower

https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/permissions?tabs=windows

Body:
I have written a xamarin forms app which uses the Plugin.BLE NuGet package to scan and connect to ble devices. It was working/debugging flawlessly on my phone until it(my phone) updated to Android 12.0 - API 31. I am using the basic vanilla implementation from the plugin:

adapter.DeviceDiscovered += (s,a) => deviceList.Add(a.Device);
await adapter.StartScanningForDevicesAsync();

I have found that Android 12 requires different runtime permissions ([https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower][1]) and I have tried to accomodate them in the manifest file:

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
    <application android:label="Rep_001.Android" android:theme="@style/MainTheme"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
    <uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower

but alas I am having no luck. I am thinking that I need to ask the user for scan and connect privileges at runtime but I am not sure how to do that as Xamarin.Essentials does not have bluetooth permissions requests.

Body:
Well, I figured it out. Within the Android Project, I created a class that inherits from Xamarin.Essentials.Permissions.BasePlatformPermission:

 public class BLEPermission : Xamarin.Essentials.Permissions.BasePlatformPermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
{
    (Android.Manifest.Permission.BluetoothScan, true),
    (Android.Manifest.Permission.BluetoothConnect, true)
}.ToArray();
}

Then within MainActivity.cs -> OnCreate() I inserted the RequestAsync immediately after the Application is loaded:

        protected override async void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());

        await Permissions.RequestAsync<BLEPermission>();
    }

Now when the app loads for the first time it asks the user for bluetooth scanning an connecting permissions. All subsequent launches do not re-prompt for permissions.
Sites/Documentation that helped along the way

https://developer.android.com/guide/topics/connectivity/bluetooth/permissions#declare-android11-or-lower

https://learn.microsoft.com/en-us/xamarin/android/app-fundamentals/permissions?tabs=windows


问:
HDMI TV sometimes not detected in windows 7? Possible to invoke Detect in code?
i have a standalone public kiosk pc that startups automatically everyday. It is connected to a HD TV and sometimes it is not detected. i have to personally go down to the PC, go to Screen Resolution and press Detect which it works.

my question is how do i know if the monitor i want it to display is connected properly in code?

thanks

答:
I did manage to find some code on the MSDN site where a user is using code to determine which type of monitor is connected. I hope this may be a good starting point for you.</p>

```<code>using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace CRT
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public class NativeMethods

        {
            [DllImport("user32.dll", EntryPoint = "MonitorFromWindow", SetLastError = true)]
            public static extern IntPtr MonitorFromWindow(
                [In] IntPtr hwnd, uint dwFlags);

            [DllImport("dxva2.dll", EntryPoint = "GetNumberOfPhysicalMonitorsFromHMONITOR", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(
                IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors);

            [DllImport("dxva2.dll", EntryPoint = "GetPhysicalMonitorsFromHMONITOR", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetPhysicalMonitorsFromHMONITOR(
                IntPtr hMonitor,
                uint dwPhysicalMonitorArraySize,
                [Out] NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray);

            [DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitors", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DestroyPhysicalMonitors(
                uint dwPhysicalMonitorArraySize, [Out] NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray);

            [DllImport("dxva2.dll", EntryPoint = "GetMonitorTechnologyType", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetMonitorTechnologyType(
                IntPtr hMonitor, ref NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE pdtyDisplayTechnologyType);

            [DllImport("dxva2.dll", EntryPoint = "GetMonitorCapabilities", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetMonitorCapabilities(
                IntPtr hMonitor, ref uint pdwMonitorCapabilities, ref uint pdwSupportedColorTemperatures);
        }

        public class NativeConstants
        {
            public const int MONITOR_DEFAULTTOPRIMARY = 1;

            public const int MONITOR_DEFAULTTONEAREST = 2;

            public const int MONITOR_DEFAULTTONULL = 0;
        }

        public class NativeStructures
        {
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct PHYSICAL_MONITOR
            {
                public IntPtr hPhysicalMonitor;

                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szPhysicalMonitorDescription;
            }

            public enum MC_DISPLAY_TECHNOLOGY_TYPE
            {
                MC_SHADOW_MASK_CATHODE_RAY_TUBE,

                MC_APERTURE_GRILL_CATHODE_RAY_TUBE,

                MC_THIN_FILM_TRANSISTOR,

                MC_LIQUID_CRYSTAL_ON_SILICON,

                MC_PLASMA,

                MC_ORGANIC_LIGHT_EMITTING_DIODE,

                MC_ELECTROLUMINESCENT,

                MC_MICROELECTROMECHANICAL,

                MC_FIELD_EMISSION_DEVICE,
            }
        }

        public Window1() { InitializeComponent(); }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            WindowInteropHelper helper = new WindowInteropHelper(this);

            IntPtr hMonitor = NativeMethods.MonitorFromWindow(helper.Handle, NativeConstants.MONITOR_DEFAULTTOPRIMARY);
            int lastWin32Error = Marshal.GetLastWin32Error();

            uint pdwNumberOfPhysicalMonitors = 0u;
            bool numberOfPhysicalMonitorsFromHmonitor = NativeMethods.GetNumberOfPhysicalMonitorsFromHMONITOR(
                hMonitor, ref pdwNumberOfPhysicalMonitors);
            lastWin32Error = Marshal.GetLastWin32Error();

            NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray =
                new NativeStructures.PHYSICAL_MONITOR[pdwNumberOfPhysicalMonitors];
            bool physicalMonitorsFromHmonitor = NativeMethods.GetPhysicalMonitorsFromHMONITOR(
                hMonitor, pdwNumberOfPhysicalMonitors, pPhysicalMonitorArray);
            lastWin32Error = Marshal.GetLastWin32Error();

            uint pdwMonitorCapabilities = 0u;
            uint pdwSupportedColorTemperatures = 0u;
            var monitorCapabilities = NativeMethods.GetMonitorCapabilities(
                pPhysicalMonitorArray[0].hPhysicalMonitor, ref pdwMonitorCapabilities, ref pdwSupportedColorTemperatures);
            lastWin32Error = Marshal.GetLastWin32Error();

            NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE type =
                NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE;
            var monitorTechnologyType = NativeMethods.GetMonitorTechnologyType(
                pPhysicalMonitorArray[0].hPhysicalMonitor, ref type);
            lastWin32Error = Marshal.GetLastWin32Error();

            var destroyPhysicalMonitors = NativeMethods.DestroyPhysicalMonitors(
                pdwNumberOfPhysicalMonitors, pPhysicalMonitorArray);
            lastWin32Error = Marshal.GetLastWin32Error();

            this.lbl.Content = type;
        }
    }
}
</code>```

Body:
I did manage to find some code on the MSDN site where a user is using code to determine which type of monitor is connected. I hope this may be a good starting point for you.

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace CRT
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public class NativeMethods

        {
            [DllImport("user32.dll", EntryPoint = "MonitorFromWindow", SetLastError = true)]
            public static extern IntPtr MonitorFromWindow(
                [In] IntPtr hwnd, uint dwFlags);

            [DllImport("dxva2.dll", EntryPoint = "GetNumberOfPhysicalMonitorsFromHMONITOR", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetNumberOfPhysicalMonitorsFromHMONITOR(
                IntPtr hMonitor, ref uint pdwNumberOfPhysicalMonitors);

            [DllImport("dxva2.dll", EntryPoint = "GetPhysicalMonitorsFromHMONITOR", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetPhysicalMonitorsFromHMONITOR(
                IntPtr hMonitor,
                uint dwPhysicalMonitorArraySize,
                [Out] NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray);

            [DllImport("dxva2.dll", EntryPoint = "DestroyPhysicalMonitors", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool DestroyPhysicalMonitors(
                uint dwPhysicalMonitorArraySize, [Out] NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray);

            [DllImport("dxva2.dll", EntryPoint = "GetMonitorTechnologyType", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetMonitorTechnologyType(
                IntPtr hMonitor, ref NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE pdtyDisplayTechnologyType);

            [DllImport("dxva2.dll", EntryPoint = "GetMonitorCapabilities", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool GetMonitorCapabilities(
                IntPtr hMonitor, ref uint pdwMonitorCapabilities, ref uint pdwSupportedColorTemperatures);
        }

        public class NativeConstants
        {
            public const int MONITOR_DEFAULTTOPRIMARY = 1;

            public const int MONITOR_DEFAULTTONEAREST = 2;

            public const int MONITOR_DEFAULTTONULL = 0;
        }

        public class NativeStructures
        {
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            public struct PHYSICAL_MONITOR
            {
                public IntPtr hPhysicalMonitor;

                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] public string szPhysicalMonitorDescription;
            }

            public enum MC_DISPLAY_TECHNOLOGY_TYPE
            {
                MC_SHADOW_MASK_CATHODE_RAY_TUBE,

                MC_APERTURE_GRILL_CATHODE_RAY_TUBE,

                MC_THIN_FILM_TRANSISTOR,

                MC_LIQUID_CRYSTAL_ON_SILICON,

                MC_PLASMA,

                MC_ORGANIC_LIGHT_EMITTING_DIODE,

                MC_ELECTROLUMINESCENT,

                MC_MICROELECTROMECHANICAL,

                MC_FIELD_EMISSION_DEVICE,
            }
        }

        public Window1() { InitializeComponent(); }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            WindowInteropHelper helper = new WindowInteropHelper(this);

            IntPtr hMonitor = NativeMethods.MonitorFromWindow(helper.Handle, NativeConstants.MONITOR_DEFAULTTOPRIMARY);
            int lastWin32Error = Marshal.GetLastWin32Error();

            uint pdwNumberOfPhysicalMonitors = 0u;
            bool numberOfPhysicalMonitorsFromHmonitor = NativeMethods.GetNumberOfPhysicalMonitorsFromHMONITOR(
                hMonitor, ref pdwNumberOfPhysicalMonitors);
            lastWin32Error = Marshal.GetLastWin32Error();

            NativeStructures.PHYSICAL_MONITOR[] pPhysicalMonitorArray =
                new NativeStructures.PHYSICAL_MONITOR[pdwNumberOfPhysicalMonitors];
            bool physicalMonitorsFromHmonitor = NativeMethods.GetPhysicalMonitorsFromHMONITOR(
                hMonitor, pdwNumberOfPhysicalMonitors, pPhysicalMonitorArray);
            lastWin32Error = Marshal.GetLastWin32Error();

            uint pdwMonitorCapabilities = 0u;
            uint pdwSupportedColorTemperatures = 0u;
            var monitorCapabilities = NativeMethods.GetMonitorCapabilities(
                pPhysicalMonitorArray[0].hPhysicalMonitor, ref pdwMonitorCapabilities, ref pdwSupportedColorTemperatures);
            lastWin32Error = Marshal.GetLastWin32Error();

            NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE type =
                NativeStructures.MC_DISPLAY_TECHNOLOGY_TYPE.MC_SHADOW_MASK_CATHODE_RAY_TUBE;
            var monitorTechnologyType = NativeMethods.GetMonitorTechnologyType(
                pPhysicalMonitorArray[0].hPhysicalMonitor, ref type);
            lastWin32Error = Marshal.GetLastWin32Error();

            var destroyPhysicalMonitors = NativeMethods.DestroyPhysicalMonitors(
                pdwNumberOfPhysicalMonitors, pPhysicalMonitorArray);
            lastWin32Error = Marshal.GetLastWin32Error();

            this.lbl.Content = type;
        }
    }
}


问:
Is there a way to check when a series is highlighted on apache echarts line chart
I'm using the Line Chart type from Apache Echarts in an Angular project and I need to know when a line has entered into the "highlight" or "emphasis" state:

This state is triggered when hovering on a line & letting the cursor there (cursor not showing on screenshot).

Using the "highlight" event from the chart instance does not work because it emits every time you move the cursor anywhere on the graph; and actually, it does not emit when you do the hover & holding.

Using the ZRender object and listening to the "mouseover" event is more accurate as it emits only when you "mouseover" a series line. However, I still don't know when the line has actually entered into the "emphasis" or "highlight" state (when the others are grayed out and the hovered line keeps its color).

```<code>this.chartInstance.getZr().on('mouseover', (event: any) => {
  console.log(event);

  // can't find anything that can tell me if a series line is highlighted or not.
  console.log((this.chartInstance as any).getModel());
  console.log((this.chartInstance as any).getModel().getSeries());
})
</code>```

Is there a flag on the series data that could tell me if one series (line) is on the "highlight" state?

Thanks in advance.

答:
Seems to work for me. Try not to log the event, instead log params and get the event from there (look at console).

let myChart02 = echarts.init(document.getElementById('echart02'));

myChart02.group = 'myGroup';

myChart02.on('mouseover', (params) => {
  console.log(params);
})

myChart02.setOption(option02);
```

Working example: https://stackblitz.com/edit/echarts-sync-zoom-only-jzkzh8?file=index.js

Body:
I'm using the Line Chart type from Apache Echarts in an Angular project and I need to know when a line has entered into the "highlight" or "emphasis" state:

This state is triggered when hovering on a line & letting the cursor there (cursor not showing on screenshot).

Using the "highlight" event from the chart instance does not work because it emits every time you move the cursor anywhere on the graph; and actually, it does not emit when you do the hover & holding.

Using the ZRender object and listening to the "mouseover" event is more accurate as it emits only when you "mouseover" a series line. However, I still don't know when the line has actually entered into the "emphasis" or "highlight" state (when the others are grayed out and the hovered line keeps its color).

this.chartInstance.getZr().on('mouseover', (event: any) => {
  console.log(event);

  // can't find anything that can tell me if a series line is highlighted or not.
  console.log((this.chartInstance as any).getModel());
  console.log((this.chartInstance as any).getModel().getSeries());
})

Is there a flag on the series data that could tell me if one series (line) is on the "highlight" state?

Thanks in advance.

Body:
Seems to work for me. Try not to log the event, instead log params and get the event from there (look at console).

let myChart02 = echarts.init(document.getElementById('echart02'));

myChart02.group = 'myGroup';

myChart02.on('mouseover', (params) => {
  console.log(params);
})

myChart02.setOption(option02);

Working example: https://stackblitz.com/edit/echarts-sync-zoom-only-jzkzh8?file=index.js


问:
how to have 2 different messages depending on user input using using the while function?
i created a code that solves mathematic problems by the user. The problems have to involve addition, subtraction, division or multiplication.  the code runs without any errors but the issue is I want the code to give two distinct messages for the user.

when the user runs the code for the first time "Please enter the problem in this format (number1 operator number2) or type 'stop' to exist"

when the user enters the problem in the wrong format "invalid enter please try again with the right format or enter 'stop' to exist'

while True:
    while True:
        problem = input("Please enter the problem in this format (number1 operator number2) or type 'stop' to exist: ").split()
        if problem[0] == 'stop':
            break
        if len(problem) != 3:
            continue
        n1,op,n2 = problem
        if any( not (n.isnumeric() or n.count('.')==1 and n.replace('.','').isnumeric()) for n in (n1,n2) ):
            continue
        if op not in ('+','-','*','/','//','**'):
        #this is the tuple of operators which tell the computer which operature the user is using
            continue
        break
    if problem[0] == 'stop':
        break
    match op:
        case '+': result = float(n1)+float(n2)
        case '-': result = float(n1)-float(n2)
        case '*': result = float(n1)*float(n2)
        case '**': result = float(n1)**float(n2)
        case '/': result = float(n1)/float(n2)
            #this will give a float answer. Ex: 1 / 9 = 0.11
        case '//': result = float(n1)//float(n2)
            #this will give an integer answer. Ex: 1 / 9 = 0
    print(f'{result:,.2f}')

```

答:
import sys

def main():
    # Define user_input variables n1, operator, and n2:
    n1, operator, n2 = None, None, None
    operators = ['+', '-', '/', '*', '**']
    while True:  # main loop
        while True:  # Input loop
            user_input = input(
                "Please enter the problem in this format (num operator num) or type 'stop' to quite:\n> ").split()
            if ''.join(user_input) == 'stop':
                print('Goodbye!')
                sys.exit()
            # Check user_input length
            if len(user_input) != 3:
                print(f'This function takes three arguments, {len(user_input)} were given.')
                continue  # continue asking for input
            # Now that the user_input length has been checked, lets assign n1, n2, and operator.
            n1, operator, n2 = user_input[0], user_input[1], user_input[2]
            if not n1.isdigit() or not n2.isdigit():
                print(f" '{n1}' or '{n2}' was not a valid digit!")
                continue  # continue asking for input
            if operator not in operators:
                print(f"'{operator}' was an invalid operator!")
                continue  # continue asking for input
            else:
                break  # break from user_input loop:
        # Join results for evaluation.
        result = ''.join((n1, operator, n2))
        print(f'You entered {n1} {operator} {n2} = {eval(result)}')

if __name__ == '__main__':
    main()

```


问:
SourceTree: Adding a custom action to open a file in an external editor
SourceTree has a window called unstaged files where it shows files whose changes have not been committed. I want to right click on the file name & open it in an external editor.
So I added a custom action -> Edit -> pathtoeditor\editor.exe $REPO\$FILE.

This launches the editor. But SourceTree also keeps showing a progress bar.

The progress bar closes only after I close the external editor.

How do I avoid this? After opening the file in the external editor, I want SourceTree's UI to return to its normal state without waiting for the editor to exit.

答:
The issue is that SourceTree is waiting for the launched process to finish (which could be useful - for example when launching a merge tool, or some other task that requires action from SourceTree when it completes).

To launch a truly independent instance of your editor, use

```<code>cmd
</code>```

as the "Script to run" and

```<code>/C start "" path_to_editor <parameters> "$REPO/$FILE"
</code>```

as the parameter.

The /C option on cmd causes the command window to close as soon as it executes the start command, and the empty first parameter to the "start" is a dummy value for the command window that will never open. If path_to_editor contains spaces, then you have to enclose it in quotations.

Body:
The issue is that SourceTree is waiting for the launched process to finish (which could be useful - for example when launching a merge tool, or some other task that requires action from SourceTree when it completes).

To launch a truly independent instance of your editor, use

cmd

as the "Script to run" and

/C start "" path_to_editor <parameters> "$REPO/$FILE"

as the parameter.

The /C option on cmd causes the command window to close as soon as it executes the start command, and the empty first parameter to the "start" is a dummy value for the command window that will never open. If path_to_editor contains spaces, then you have to enclose it in quotations.