问:
Disk Storage alert email - Powershell
Script originally created by GhillieHammer

I've added additional features to work for me.

```<code># $drives = @("D","E","F");
$drives = $null

# The minimum disk size to check for raising the warning
$minSize = 20GB
$MathminSize = [math]::round($minSize/1GB,2)
$minString = ($MathminSize).ToString()
$minString = $minString + "GB"

$email_to_addressArray = @("");
# $email_to_addressArray = @("toSingle@company.com")

#Set a couple needed variables
$SendIt = $Null
$ThisHost = $env:computername
$IPAddy = Invoke-RestMethod -Uri ('http://ipinfo.io/'+(Invoke-WebRequest -uri "http://ifconfig.me/ip").Content) | Select ip

#Check for $Drives query mode and make an array of them
if ($drives -eq $null -Or $drives -lt 1) {

    $localVolumes = Get-WmiObject win32_volume;
    $drives = @();

    foreach ($vol in $localVolumes) {

        if ($vol.DriveType -eq 3 -And $vol.DriveLetter -ne $null ) {

          $drives += $vol.DriveLetter[0];

        }

    }

}

# Enumerate through the array of drives
# check to see if any are below minimum
# if so, set a flag saying as much and then
# add them and their information to the array we'll be adding to the email
foreach ($d in $drives) {

    $disk = Get-PSDrive $d;
    $MathDiskFree = [math]::round($disk.Free/1GB,2)
    $MathDiskUsed = [math]::round($disk.Used/1GB,2)
    $MathDisktotal = [math]::round($MathDiskFree + $MathDiskUsed)
    $MathDiskPerc = ($MathDiskFree / $MathDiskUsed).tostring("P")

    if ($disk.Free -lt $minSize) {

        $SendIt = 1
        $space += ("Free space on drive " + $d + " = " + $MathDiskFree + "GB. This is equal to only " + $MathDiskPerc + "  of the " + $MathDisktotal + "GB total space available on this drive.<br>")

    }

}
# Check the flag to see if it's set, meaning there's at least one drive below minimum free space, and if so, fire off the email(s)
If ($SendIt -eq 1) {

    # Enumerate through the array of email addresses and fire off a formatted email to each
    foreach ($toAddress in $email_to_addressArray) {

$User = "diskspace@"
$File = (Get-Content C:\Temp\pw.txt | ConvertTo-SecureString)

$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $User, $File

        $To = $toAddress
        $from = ""
        $EmailSubject = "WARNING: one or more disk on $ThisHost low on space"
        $smtp = "auth.smtp.1and1.co.uk"

        $DefaultMessage="
            <p>Dear colleague,</p>
            <p>There is a hard drive space issue on $ThisHost IPv4: $IPAddy </p>
            <p>$space<br></p>
            <p>This message only fires off if one or more disks have less than $minString GB of free space left.</p>
            <p>Sincerely,<br>
              Robot Monitor.<br><br>
            </p>"

        $MailMessage = @{
                To = $To
                From = $from
                # BCC = $Bcc
                Subject = $EmailSubject
                Body = $DefaultMessage
                priority = "High"
                Smtpserver = $smtp
                Credential = $MyCredential
                ErrorAction = "SilentlyContinue"
            }

        Send-MailMessage @MailMessage -bodyashtml

    }

}
</code>```

The script works perfectly but can't seem to get it stop generating the following information

Can't seem to find or understand how it's generating additional lines of text. Any insight would be greatly appreciated!

答:
Try using a more simplified code like the one below. I use this with a scheduled task on the machines I need it on. It only sends on email if disk space gets below threshold. You could modify it to work with the other drives you have. It's not really clear how you are getting multiple line output but modifying it would help resolve your problem and simplify your code.</p>

```<code>$minGbThreshold = 10;
$computers = $env:COMPUTERNAME;
$smtpAddress = "smtp.yourdomain.com";
$toAddress = "anyone@gmail.com";
$fromAddress = "someone@gmail.com";
foreach($computer in $computers)
{
    $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3";
    $computer = $computer.toupper();
    $deviceID = $disk.DeviceID;
    foreach($disk in $disks)
    {
        $freeSpaceGB = [Math]::Round([float]$disk.FreeSpace / 1073741824, 2);
        if($freeSpaceGB -lt $minGbThreshold)
        {
            $smtp = New-Object Net.Mail.SmtpClient($smtpAddress)
            $msg = New-Object Net.Mail.MailMessage
            $msg.To.Add($toAddress)
            $msg.From = $fromAddress
            $msg.Subject = “Diskspace below threshold ” + $computer + "\" + $disk.DeviceId
            $msg.Body = $computer + "\" + $disk.DeviceId + " " + $freeSpaceGB + "GB Remaining";
            $smtp.Send($msg)
        }
    }
}
</code>```

Title: Disk Storage alert email - Powershell

Body:
Script originally created by GhillieHammer

I've added additional features to work for me.

# $drives = @("D","E","F");
$drives = $null

# The minimum disk size to check for raising the warning
$minSize = 20GB
$MathminSize = [math]::round($minSize/1GB,2)
$minString = ($MathminSize).ToString()
$minString = $minString + "GB"

$email_to_addressArray = @("");
# $email_to_addressArray = @("toSingle@company.com")

#Set a couple needed variables
$SendIt = $Null
$ThisHost = $env:computername
$IPAddy = Invoke-RestMethod -Uri ('http://ipinfo.io/'+(Invoke-WebRequest -uri "http://ifconfig.me/ip").Content) | Select ip

#Check for $Drives query mode and make an array of them
if ($drives -eq $null -Or $drives -lt 1) {

    $localVolumes = Get-WmiObject win32_volume;
    $drives = @();

    foreach ($vol in $localVolumes) {

        if ($vol.DriveType -eq 3 -And $vol.DriveLetter -ne $null ) {

          $drives += $vol.DriveLetter[0];

        }

    }

}

# Enumerate through the array of drives
# check to see if any are below minimum
# if so, set a flag saying as much and then
# add them and their information to the array we'll be adding to the email
foreach ($d in $drives) {

    $disk = Get-PSDrive $d;
    $MathDiskFree = [math]::round($disk.Free/1GB,2)
    $MathDiskUsed = [math]::round($disk.Used/1GB,2)
    $MathDisktotal = [math]::round($MathDiskFree + $MathDiskUsed)
    $MathDiskPerc = ($MathDiskFree / $MathDiskUsed).tostring("P")

    if ($disk.Free -lt $minSize) {

        $SendIt = 1
        $space += ("Free space on drive " + $d + " = " + $MathDiskFree + "GB. This is equal to only " + $MathDiskPerc + "  of the " + $MathDisktotal + "GB total space available on this drive.
")

    }

}
# Check the flag to see if it's set, meaning there's at least one drive below minimum free space, and if so, fire off the email(s)
If ($SendIt -eq 1) {

    # Enumerate through the array of email addresses and fire off a formatted email to each
    foreach ($toAddress in $email_to_addressArray) {

$User = "diskspace@"
$File = (Get-Content C:\Temp\pw.txt | ConvertTo-SecureString)

$MyCredential = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $User, $File

        $To = $toAddress
        $from = ""
        $EmailSubject = "WARNING: one or more disk on $ThisHost low on space"
        $smtp = "auth.smtp.1and1.co.uk"

        $DefaultMessage="

Dear colleague,

There is a hard drive space issue on $ThisHost IPv4: $IPAddy

$space

This message only fires off if one or more disks have less than $minString GB of free space left.

Sincerely,

              Robot Monitor.

"

        $MailMessage = @{
                To = $To
                From = $from
                # BCC = $Bcc
                Subject = $EmailSubject
                Body = $DefaultMessage
                priority = "High"
                Smtpserver = $smtp
                Credential = $MyCredential
                ErrorAction = "SilentlyContinue"
            }

        Send-MailMessage @MailMessage -bodyashtml

    }

}

The script works perfectly but can't seem to get it stop generating the following information

Can't seem to find or understand how it's generating additional lines of text. Any insight would be greatly appreciated!

Body:
Try using a more simplified code like the one below. I use this with a scheduled task on the machines I need it on. It only sends on email if disk space gets below threshold. You could modify it to work with the other drives you have. It's not really clear how you are getting multiple line output but modifying it would help resolve your problem and simplify your code.

$minGbThreshold = 10;
$computers = $env:COMPUTERNAME;
$smtpAddress = "smtp.yourdomain.com";
$toAddress = "anyone@gmail.com";
$fromAddress = "someone@gmail.com";
foreach($computer in $computers)
{
    $disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3";
    $computer = $computer.toupper();
    $deviceID = $disk.DeviceID;
    foreach($disk in $disks)
    {
        $freeSpaceGB = [Math]::Round([float]$disk.FreeSpace / 1073741824, 2);
        if($freeSpaceGB -lt $minGbThreshold)
        {
            $smtp = New-Object Net.Mail.SmtpClient($smtpAddress)
            $msg = New-Object Net.Mail.MailMessage
            $msg.To.Add($toAddress)
            $msg.From = $fromAddress
            $msg.Subject = “Diskspace below threshold ” + $computer + "\" + $disk.DeviceId
            $msg.Body = $computer + "\" + $disk.DeviceId + " " + $freeSpaceGB + "GB Remaining";
            $smtp.Send($msg)
        }
    }
}


来源: stackexchange

问:
Setup Rabbitmq consumer in dotnet core by timed background task
I try to setup the rabbitmq consumer by timed background task, however, it's not always consuming message correctly. It seems to get message from queue, but does not log the received message correctly. This seems to be very weird. I guess it's somehow related to the event handler receiving message not executed properly, but I just cannot figure out why.

I do the timed background task as discussed in Background tasks with hosted services in ASP.NET Core because I want to avoid having a long lived connection. I feel it's more safe to create new connections to queue when needed.

However, when using background service with long lived connection, everything actually works fine so far.

Can someone tell me what's wrong about the following code?

```<code>// consumer part
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace play_mq
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    logging.AddConsole();
                })
                .ConfigureServices(services =>
                {
                    services.AddHostedService<MessageListener>();
                });
    }

    public class MessageListener : IHostedService, IDisposable
    {
        private readonly IOptions<RabbitOptions> _rabbitOptions;
        private readonly ILogger<MessageListener> _logger;
        private Timer _timer;
        private int executionCount = 0;

        public MessageListener(ILogger<MessageListener> logger, IOptions<RabbitOptions> rabbitOptions)
        {
            _logger = logger;
            _rabbitOptions = rabbitOptions;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;

        }

        private void DoWork(object state)
        {
            var count = Interlocked.Increment(ref executionCount);

            _logger.LogInformation(
                "MessageListener is working. Count: {Count}", count);

            var factory = new ConnectionFactory()
            {
                HostName = "localhost"
            };

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body.ToArray());
                    _logger.LogInformation($"consume {message}");
                };
                channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MessageListener is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }

}
</code>```

```<code>// Sender comes from official example
using System;
using RabbitMQ.Client;
using System.Text;

namespace ConsoleMq
{
    class Send
    {
        public static void Main()
        {
            var factory = new ConnectionFactory() { HostName = "localhost", Port = 14000 };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

                string message = "Hello World!";
                var body = Encoding.UTF8.GetBytes(message);

                channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }
}
</code>```

答:
It seems to get message from queue, but does not log the received message correctly.

Reason:

```<code>channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
</code>```

autoAck set to true, It ack positive to a broker before receiving a message. and broker remove it from the queue once it ack +

Solution: Instead of Setting ack(true) there(Set auroAck = false), And Ack when you receive message

```<code>consumer.Received += (model, ea) =>
            {
               channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
               //Other method available for negative ack
            };
</code>```

I want to avoid having a long lived connection. I feel it's more safe to create new ?connections to queue when needed.

For a better answer to your question, You can check MassTransit(RabbitMQ wrapper)  code.

And to receive messages as it publishes

```<code>public class MessageListener : IHostedService, IDisposable
    {
        private readonly IOptions<RMQConfig> _rabbitOptions;
        private readonly ILogger<MessageListener> _logger;
        private Timer _timer;
        private int executionCount = 0;
        private readonly IConnection _connection;

        public MessageListener(ILogger<MessageListener> logger, IOptions<RMQConfig> rabbitOptions)
        {
            _logger = logger;
            _rabbitOptions = rabbitOptions;
            var factory = new ConnectionFactory()
            {
                HostName = "localhost"
            };
            _connection = factory.CreateConnection();
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;

        }

        private void DoWork(object state)
        {
            var count = Interlocked.Increment(ref executionCount);

            _logger.LogInformation(
                "MessageListener is working. Count: {Count}", count);

            // using (var connection = factory.CreateConnection())
            // using (var channel = connection.CreateModel())
            // {
            var channel = _connection.CreateModel();

            channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body.ToArray());
                _logger.LogInformation($"consume {message}");
            };
            channel.BasicConsume(queue: "hello", autoAck: false, consumer: consumer);
            // }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MessageListener is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            //Close _connection
            _timer?.Dispose();
        }
    }
</code>```

I faced the same issue a few months back, Hope It will help others.

ContentLicense: CC BY-SA 4.0

Body:
I try to setup the rabbitmq consumer by timed background task, however, it's not always consuming message correctly. It seems to get message from queue, but does not log the received message correctly. This seems to be very weird. I guess it's somehow related to the event handler receiving message not executed properly, but I just cannot figure out why.

I do the timed background task as discussed in Background tasks with hosted services in ASP.NET Core because I want to avoid having a long lived connection. I feel it's more safe to create new connections to queue when needed.

However, when using background service with long lived connection, everything actually works fine so far.

Can someone tell me what's wrong about the following code?

// consumer part
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace play_mq
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging =>
                {
                    logging.AddConsole();
                })
                .ConfigureServices(services =>
                {
                    services.AddHostedService<MessageListener>();
                });
    }

    public class MessageListener : IHostedService, IDisposable
    {
        private readonly IOptions<RabbitOptions> _rabbitOptions;
        private readonly ILogger<MessageListener> _logger;
        private Timer _timer;
        private int executionCount = 0;

        public MessageListener(ILogger<MessageListener> logger, IOptions<RabbitOptions> rabbitOptions)
        {
            _logger = logger;
            _rabbitOptions = rabbitOptions;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;

        }

        private void DoWork(object state)
        {
            var count = Interlocked.Increment(ref executionCount);

            _logger.LogInformation(
                "MessageListener is working. Count: {Count}", count);

            var factory = new ConnectionFactory()
            {
                HostName = "localhost"
            };

            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body.ToArray());
                    _logger.LogInformation($"consume {message}");
                };
                channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
            }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MessageListener is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            _timer?.Dispose();
        }
    }

}

// Sender comes from official example
using System;
using RabbitMQ.Client;
using System.Text;

namespace ConsoleMq
{
    class Send
    {
        public static void Main()
        {
            var factory = new ConnectionFactory() { HostName = "localhost", Port = 14000 };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

                string message = "Hello World!";
                var body = Encoding.UTF8.GetBytes(message);

                channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }
}

Body:
It seems to get message from queue, but does not log the received message correctly.

Reason:

channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);

autoAck set to true, It ack positive to a broker before receiving a message. and broker remove it from the queue once it ack +

Solution: Instead of Setting ack(true) there(Set auroAck = false), And Ack when you receive message

consumer.Received += (model, ea) =>
            {
               channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
               //Other method available for negative ack
            };

I want to avoid having a long lived connection. I feel it's more safe to create new ?connections to queue when needed.

For a better answer to your question, You can check MassTransit(RabbitMQ wrapper)  code.

And to receive messages as it publishes

public class MessageListener : IHostedService, IDisposable
    {
        private readonly IOptions<RMQConfig> _rabbitOptions;
        private readonly ILogger<MessageListener> _logger;
        private Timer _timer;
        private int executionCount = 0;
        private readonly IConnection _connection;

        public MessageListener(ILogger<MessageListener> logger, IOptions<RMQConfig> rabbitOptions)
        {
            _logger = logger;
            _rabbitOptions = rabbitOptions;
            var factory = new ConnectionFactory()
            {
                HostName = "localhost"
            };
            _connection = factory.CreateConnection();
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            _timer = new Timer(DoWork, null, TimeSpan.Zero,
                TimeSpan.FromSeconds(5));

            return Task.CompletedTask;

        }

        private void DoWork(object state)
        {
            var count = Interlocked.Increment(ref executionCount);

            _logger.LogInformation(
                "MessageListener is working. Count: {Count}", count);

            // using (var connection = factory.CreateConnection())
            // using (var channel = connection.CreateModel())
            // {
            var channel = _connection.CreateModel();

            channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);
            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body.ToArray());
                _logger.LogInformation($"consume {message}");
            };
            channel.BasicConsume(queue: "hello", autoAck: false, consumer: consumer);
            // }
        }

        public Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("MessageListener is stopping.");

            _timer?.Change(Timeout.Infinite, 0);

            return Task.CompletedTask;
        }

        public void Dispose()
        {
            //Close _connection
            _timer?.Dispose();
        }
    }

I faced the same issue a few months back, Hope It will help others.


问:
How to generate game pins
I am developing a game that requires a game PIN to join, similar to Kahoot in that regard I suppose. E.g. KA1PN2XR. I was thinking of making it 8 characters and alphanumeric, so I'm not worried about running out of combinations as there are 36^8 or about 2.8 trillion (capital letters) of them, and games will be removed once everyone has left.

However, I am wondering what is an efficient way to generate these pins? Should I use a while loop that generates one until it finds one that isn't in the database? Seems inefficient but I can't think of a much better method.

Thanks.

答:
if you make a random pin of 8 chars with slicing of uuid like this:

```<code>import uuid

print str(uuid.uuid4())[:8]
</code>```

regarding of deleting pin after finishing game, and assuming you have 1000 users per second and each game lasts 30 minutes, probability of repeating of a pin in a second is approximately zero:
(1000*30*60)/(35^8)=7.99333749768639e-07
35 is number of alphanumeric states and 8 is number of slicing chars from uuid.
you can increase or decrease number of slicing chars based on estimating of pins generated in a second and number of users and risk of repeating.

in the worst case if you generate a uuid with 32 chars and not deleting them:
after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%.

check the uniqueness of these pins is very inefficient solution for problems like these. you are deleting pins after game, and this is the heaven of random key generation algorithmes that their goals are not generating duplicate key in long run generation.

Title: How to generate game pins

Body:
if you make a random pin of 8 chars with slicing of uuid like this:

import uuid

print str(uuid.uuid4())[:8]

regarding of deleting pin after finishing game, and assuming you have 1000 users per second and each game lasts 30 minutes, probability of repeating of a pin in a second is approximately zero:
(1000*30*60)/(35^8)=7.99333749768639e-07
35 is number of alphanumeric states and 8 is number of slicing chars from uuid.
you can increase or decrease number of slicing chars based on estimating of pins generated in a second and number of users and risk of repeating.

in the worst case if you generate a uuid with 32 chars and not deleting them:
after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%.

check the uniqueness of these pins is very inefficient solution for problems like these. you are deleting pins after game, and this is the heaven of random key generation algorithmes that their goals are not generating duplicate key in long run generation.


问:
Apache NiFi : How to fetch data from Cassandra table whenever table record is getting modified
I have Cassandra as the database, We are using "QueryCassandra" processor to fetch values from Cassandra table to an output port,
Which uses a select query to fetch the records. I have a use case mentioned below.

1) First time all the records need to be fetched from Cassandra and transferred to the output port, that's happening now. (i.e  All data is frequently fetched from the table at particular time interval as we mention in Run Schedule)

2) Later whenever the Cassandra table is modified (Insert New Record or Row Updated or Row delete) then only the records need to be sent to the output port,
is there any way we can achieve this instead of fetching every time intervals?

Sample Nifi Template

答:
This isn't currently possible with NiFi (1.11.4 at the time of this writing), we'd need either a Cassandra version of QueryDatabaseTable (where you provide a column that only increases, like timestamp) or a CaptureChangeCassandra processor where we use a CommitLogReader to read the commit log rather than querying the table itself.

Please feel free to write a New Feature Jira case to add CDC capabilities for Cassandra.


问:
STM32 HAL Nucleo F446RE Quadrature Encoder
I have a problem with the quadrature encoder mode on timer TIM3 of my
STM32F446RE /
NUCLEO-F446RE:

TIM3 counts on every rising edge on the first signal.
The CNT register counts up and I read the value with 1 Hz and then
I set the register to 0.

When I look on the
oscilloscope
the frequency is half as high as the value from the
CNT register output (1hz).

Why?

TIM3 counts on both edges on the first signal.
The
CNT register output (1 Hz)
is completely wrong.

My configuration is:

```<code>GPIO_InitTypeDef sInitEncoderPin1;
sInitEncoderPin1.Pin                    = pin1Encoder.pin;  // A GPIO_PIN_6
sInitEncoderPin1.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin1.Pull                   = GPIO_PULLUP;
sInitEncoderPin1.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin1.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3

GPIO_InitTypeDef sInitEncoderPin2;
sInitEncoderPin2.Pin                    = pin2Encoder.pin; // A GPIO_PIN_7
sInitEncoderPin2.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin2.Pull                   = GPIO_PULLUP;
sInitEncoderPin2.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin2.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3

HAL_GPIO_Init(GPIOA, &sInitEncoderPin1);
HAL_GPIO_Init(GPIOA, &sInitEncoderPin2);

encoderTimer.Init.Period                        = 0xffff;
encoderTimer.Init.Prescaler                     = 0;
encoderTimer.Init.CounterMode                   = TIM_COUNTERMODE_UP;
encoderTimer.Init.ClockDivision                 = TIM_CLOCKDIVISION_DIV1;
encoderTimer.Init.RepetitionCounter             = 0;

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 1);

encoder.EncoderMode                             = TIM_ENCODERMODE_TI1;
encoder.IC1Filter                               = 0x0f;
encoder.IC1Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING; // TIM_INPUTCHANNELPOLARITY_BOTHEDGE
encoder.IC1Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC1Selection                            = TIM_ICSELECTION_DIRECTTI;

encoder.IC2Filter                               = 0x0f;
encoder.IC2Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING;
encoder.IC2Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC2Selection                            = TIM_ICSELECTION_DIRECTTI;

HAL_TIM_Encoder_Init(&encoderTimer, &encoder);
HAL_TIM_Encoder_Start_IT(&encoderTimer, TIM_CHANNEL_ALL);
</code>```

答:
The
oscilloscope screenshot
shows a frequency of about 416 Hz.

The values shown in the
first shell output
are (very roughly!) twice as high (as the question points out already).
This appears (nearly...) correct to me since the shown configuration

```<code>encoder.EncoderMode = TIM_ENCODERMODE_TI1;
</code>```

selects the "X2 resolution encoder mode", which counts 2 CNT increments per signal period.
In an application note on
timer overview,
(Sec. 4.3.4 / Fig. 7) there is an illustrative diagram how the encoder mode works in detail.

The
second screenshot
results from an incorrect TIM3 configuration:
The encoder mode (TIM_ENCODERMODE_TI1) assumes that both channels trigger only upon directed flanks in an alternating way (see the AN link above).

If one of the two channels triggers twice as many events due to
configuration

```<code>encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE,
</code>```

the counter will only count up one position and then "recognize" a "reversal" event (= change of direction).
Keeping in mind that

```<code>65535u = 0xFFFF = -1
</code>```

the second screenshot only shows values -1, 0, +1 - which fits perfectly with this explanation.

The question remains why the first screenshot shows (reproducible) measurements between 800 and 822.
I assume that

the physical source of the encoder signal runs at a constant pace

the 1 Hz timer that triggered shell output is independent from TIM3, and

it has been started before the encoder timer
(i.e., above the shown code sample).

This may explain why the first two values look like nonsense (0: TIM3 has not been started yet. 545: TIM3 has been started during the shell output timer period).
Discarding the first two measurement samples, the average and standard deviation, resp., of the measured signal frequency are

808,9091 +/- 0,5950 [X2 increments per second]

404,4545 +/- 0,2975 [Hz]

which corresponds to a period of

2,4331 +/- 0,003 [ms].

Hence, the measured frequency is too low by about 11 Hz, i.e., measured period too high by nearly 30 µs, and this error is clearly beyond the statistical noise.

The question gives a hint where this error might come from:

The CNT register counts up and I read the value with 1 Hz and then I set the register to 0.

Whenever the 1 Hz "polling timer" expires, it triggers an interrupt
(or a logical event in polling software).

Processing of this interrupt/event may be delayed a little,
depending on other software (IRQ: deactivation times elsewhere in the software,
Polling: loop duration until event is polled).

Software reads CNT value.

Software resets CNT value to zero,
discarding further increments since the CNT value has been read.

TIM3 continues counting (from zero).

This hints that software needs 30 µs between (3.) and (4.), which would be quite a lot of time on an STM32F4.

Edit: I just re-checked the oscilloscope screenshot. The error is visible, but I believe it is smaller than I originally assumed (from counting flanks in the picture).

Body:
I have a problem with the quadrature encoder mode on timer TIM3 of my
STM32F446RE /
NUCLEO-F446RE:

TIM3 counts on every rising edge on the first signal.
The CNT register counts up and I read the value with 1 Hz and then
I set the register to 0.

When I look on the
oscilloscope
the frequency is half as high as the value from the
CNT register output (1hz).

Why?

TIM3 counts on both edges on the first signal.
The
CNT register output (1 Hz)
is completely wrong.

My configuration is:

GPIO_InitTypeDef sInitEncoderPin1;
sInitEncoderPin1.Pin                    = pin1Encoder.pin;  // A GPIO_PIN_6
sInitEncoderPin1.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin1.Pull                   = GPIO_PULLUP;
sInitEncoderPin1.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin1.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3

GPIO_InitTypeDef sInitEncoderPin2;
sInitEncoderPin2.Pin                    = pin2Encoder.pin; // A GPIO_PIN_7
sInitEncoderPin2.Mode                   = GPIO_MODE_AF_PP;
sInitEncoderPin2.Pull                   = GPIO_PULLUP;
sInitEncoderPin2.Speed                  = GPIO_SPEED_HIGH;
sInitEncoderPin2.Alternate              = altFunctionEncoder; // GPIO_AF2_TIM3

HAL_GPIO_Init(GPIOA, &sInitEncoderPin1);
HAL_GPIO_Init(GPIOA, &sInitEncoderPin2);

encoderTimer.Init.Period                        = 0xffff;
encoderTimer.Init.Prescaler                     = 0;
encoderTimer.Init.CounterMode                   = TIM_COUNTERMODE_UP;
encoderTimer.Init.ClockDivision                 = TIM_CLOCKDIVISION_DIV1;
encoderTimer.Init.RepetitionCounter             = 0;

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 1);

encoder.EncoderMode                             = TIM_ENCODERMODE_TI1;
encoder.IC1Filter                               = 0x0f;
encoder.IC1Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING; // TIM_INPUTCHANNELPOLARITY_BOTHEDGE
encoder.IC1Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC1Selection                            = TIM_ICSELECTION_DIRECTTI;

encoder.IC2Filter                               = 0x0f;
encoder.IC2Polarity                             = TIM_INPUTCHANNELPOLARITY_RISING;
encoder.IC2Prescaler                            = TIM_ICPSC_DIV1;
encoder.IC2Selection                            = TIM_ICSELECTION_DIRECTTI;

HAL_TIM_Encoder_Init(&encoderTimer, &encoder);
HAL_TIM_Encoder_Start_IT(&encoderTimer, TIM_CHANNEL_ALL);

Body:
The
oscilloscope screenshot
shows a frequency of about 416 Hz.

The values shown in the
first shell output
are (very roughly!) twice as high (as the question points out already).
This appears (nearly...) correct to me since the shown configuration

encoder.EncoderMode = TIM_ENCODERMODE_TI1;

selects the "X2 resolution encoder mode", which counts 2 CNT increments per signal period.
In an application note on
timer overview,
(Sec. 4.3.4 / Fig. 7) there is an illustrative diagram how the encoder mode works in detail.

The
second screenshot
results from an incorrect TIM3 configuration:
The encoder mode (TIM_ENCODERMODE_TI1) assumes that both channels trigger only upon directed flanks in an alternating way (see the AN link above).

If one of the two channels triggers twice as many events due to
configuration

encoder.IC1Polarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE,

the counter will only count up one position and then "recognize" a "reversal" event (= change of direction).
Keeping in mind that

65535u = 0xFFFF = -1

the second screenshot only shows values -1, 0, +1 - which fits perfectly with this explanation.

The question remains why the first screenshot shows (reproducible) measurements between 800 and 822.
I assume that

the physical source of the encoder signal runs at a constant pace

the 1 Hz timer that triggered shell output is independent from TIM3, and

it has been started before the encoder timer
(i.e., above the shown code sample).

This may explain why the first two values look like nonsense (0: TIM3 has not been started yet. 545: TIM3 has been started during the shell output timer period).
Discarding the first two measurement samples, the average and standard deviation, resp., of the measured signal frequency are

808,9091 +/- 0,5950 [X2 increments per second]

404,4545 +/- 0,2975 [Hz]

which corresponds to a period of

2,4331 +/- 0,003 [ms].

Hence, the measured frequency is too low by about 11 Hz, i.e., measured period too high by nearly 30 µs, and this error is clearly beyond the statistical noise.

The question gives a hint where this error might come from:

The CNT register counts up and I read the value with 1 Hz and then I set the register to 0.

Whenever the 1 Hz "polling timer" expires, it triggers an interrupt
(or a logical event in polling software).

Processing of this interrupt/event may be delayed a little,
depending on other software (IRQ: deactivation times elsewhere in the software,
Polling: loop duration until event is polled).

Software reads CNT value.

Software resets CNT value to zero,
discarding further increments since the CNT value has been read.

TIM3 continues counting (from zero).

This hints that software needs 30 µs between (3.) and (4.), which would be quite a lot of time on an STM32F4.

Edit: I just re-checked the oscilloscope screenshot. The error is visible, but I believe it is smaller than I originally assumed (from counting flanks in the picture).


问:
Count blank cells in a row except the ones on both sides
My data looks like below. I want to count consecutive blank cells in a row except the blank cells at the beginning and at the end. My logic is to return the max. For the case below, the returned value should be 2, not 5.

答:
You can do this with a formula, using the following criteria:

IsBlank(cell) : the cell itself should be blank.

IsBlank(cell.Offset(0,-1)) : the cell to the left should be blank (in order not to count the beginning of the series)

IsBlank(cell.Offset(0,1)) : the cell to the right should be blank (in order not to count the ending of the series)

cell.Col <> 1 : in order not to count the beginning of the worksheet

IsBlank(cell.Offset(-1,1)) : in order not to count the most right blank cell


问:
How to assign an ID to identify duplicate array elements?
I have a multi-dimensional array which contains a string and another array for each element.

```<code>duplicates =
[["link_A", [247936, 672212, 248156, 671720]],
 ["link_B", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["link_C", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["link_D", [247471, 671767, 247567, 671846]],
 ["link_E", [247471, 671767, 247567, 671846]],    # Same coordinates as previous line
 ["link_F", [247567, 671846, 247775, 671680]],
 ["link_G", [247567, 671846, 247775, 671680]]]    # Same coordinates as previous line
</code>```

I have my data in a format that I want in order to go through the "duplicates" array using "each" and export the data to .csv.

The only thing I want at this point is for an assigned ID/number for every duplicate that has the same coordinates. Happy to have it as an element in the array, such as:

Desired Output:

```<code>duplicates =
[["1", "link_A", [247936, 672212, 248156, 671720]],
 ["1", "link_B", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["1", "link_C", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["2", "link_D", [247471, 671767, 247567, 671846]],
 ["2", "link_E", [247471, 671767, 247567, 671846]],    # Same coordinates as previous line
 ["3", "link_F", [247567, 671846, 247775, 671680]],
 ["3", "link_G", [247567, 671846, 247775, 671680]]]    # Same coordinates as previous line
</code>```

What's the best way of going about this?

Many thanks.

Edit:

Thank you for the responses. The current 3 answers (from 1. Siim Liiser, 2. Cary Swoveland and 3. iGian) all work well for me with slight variation (I believe - correct me if I'm wrong!):

Doesn't mutate "duplicates" // Doesn't assume in order

Doesn't mutate "duplicates" // Assumes duplicates in order

Mutates "duplicates" // Doesn't assume in order

I didn't mention it in the question but I was okay with duplicates itself being mutated. I had previously used "group_by" (little bit more info below) to create duplicates so the order shouldn't really matter either. Thanks again.

Original array (seen as 'segment_store' below) at very start holds the link name (e.g. "link_A") and an array of coords (two XY coords) - these represent link segments. As I was looking to find duplicates, I used:

```<code>duplicates = segment_store.group_by{|i| i[1]}.select{|k,v| v.length > 1}.values.flatten(1)
</code>```

to get duplicates as seen in original question (pre-edit).

答:
Here's a solution using an infinite enumerator to hold the ids and a hash to cache the first occurrence of an array.

```<code>enum = 1.step
duplicates.each_with_object({}).map do |(string, array), cache|
  [cache[array] ||= enum.next, string, array]
end
</code>```

Call .to_s on the first element to get an identical result to yours.

On average should be O(n) time with O(n) extra space.

Does not assume duplicates being consecutive. If they are always consecutive as in your example, then a different algorithm could easily be more space efficient.

Body:
I have a multi-dimensional array which contains a string and another array for each element.

duplicates =
[["link_A", [247936, 672212, 248156, 671720]],
 ["link_B", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["link_C", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["link_D", [247471, 671767, 247567, 671846]],
 ["link_E", [247471, 671767, 247567, 671846]],    # Same coordinates as previous line
 ["link_F", [247567, 671846, 247775, 671680]],
 ["link_G", [247567, 671846, 247775, 671680]]]    # Same coordinates as previous line

I have my data in a format that I want in order to go through the "duplicates" array using "each" and export the data to .csv.

The only thing I want at this point is for an assigned ID/number for every duplicate that has the same coordinates. Happy to have it as an element in the array, such as:

Desired Output:

duplicates =
[["1", "link_A", [247936, 672212, 248156, 671720]],
 ["1", "link_B", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["1", "link_C", [247936, 672212, 248156, 671720]],    # Same coordinates as previous line
 ["2", "link_D", [247471, 671767, 247567, 671846]],
 ["2", "link_E", [247471, 671767, 247567, 671846]],    # Same coordinates as previous line
 ["3", "link_F", [247567, 671846, 247775, 671680]],
 ["3", "link_G", [247567, 671846, 247775, 671680]]]    # Same coordinates as previous line

What's the best way of going about this?

Many thanks.

Edit:

Thank you for the responses. The current 3 answers (from 1. Siim Liiser, 2. Cary Swoveland and 3. iGian) all work well for me with slight variation (I believe - correct me if I'm wrong!):

Doesn't mutate "duplicates" // Doesn't assume in order

Doesn't mutate "duplicates" // Assumes duplicates in order

Mutates "duplicates" // Doesn't assume in order

I didn't mention it in the question but I was okay with duplicates itself being mutated. I had previously used "group_by" (little bit more info below) to create duplicates so the order shouldn't really matter either. Thanks again.

Original array (seen as 'segment_store' below) at very start holds the link name (e.g. "link_A") and an array of coords (two XY coords) - these represent link segments. As I was looking to find duplicates, I used:

duplicates = segment_store.group_by{|i| i[1]}.select{|k,v| v.length > 1}.values.flatten(1)

to get duplicates as seen in original question (pre-edit).

Body:
Here's a solution using an infinite enumerator to hold the ids and a hash to cache the first occurrence of an array.

enum = 1.step
duplicates.each_with_object({}).map do |(string, array), cache|
  [cache[array] ||= enum.next, string, array]
end

Call .to_s on the first element to get an identical result to yours.

On average should be O(n) time with O(n) extra space.

Does not assume duplicates being consecutive. If they are always consecutive as in your example, then a different algorithm could easily be more space efficient.


问:
Can anyone suggest data science project
I just completed data science topic i want to fo a mini project in data science can anyone suggest me a project . I searched a lot in google but i not found any projects can anyonr suggest a project</p>

答:
The beauty of data science is that the project can be anything you're curious about. To figure out what kind of project you want to tackle, what kind of questions do you want to know the answers to?

At the top of my head, you could explore:

the various COVID related data try to find any insights or simply

the price differences of peaches around different areas of Atlanta,
GA

is there a particular skill you want to improve such as time series analysis, classification, or regression?

Find a question you want to answer or a project that will improve your skill in a certain area.

Title: Can anyone suggest data science project


问:
Docusign oauth flow: which one can i use for my expample
i need to sing to my new customers a document with two options :
- Document A : sent via email to be signed by the customer
- Document B : sent via email to be signed by the customer and his parent
I used for that the webhook and it work as well for demo version. My question is which oauth flow i have to use i hope you can provide an api example if possible. Thanks for your help.</p>

答: The question is who initiates the envelope? If it is an employee then auth code grant. If it is either the signer or an autonomous process (eg in reaction to an entry in a database) then JWT grant</p>


问:
How to switch between shiny tab panels from inside a module?
I'm trying to modularize a shiny app that has a button to reactively switch between tabPanels using updateTabsetPanel(). This works in the non-modular app, but doesn't when making the reactive is contained in a module.  I think it has to do with the panels being outside the scope of the module.  Below are minimal examples (the non-modular version that works and the modular version that does not).  Is there a way to have the module talk to the tabPanels?

```<code># Non-modular version
library(shiny)
library(shinydashboard)

ui <- fluidPage(
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1",
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3,
                       actionButton("switchbutton", "Click to swtich")
                   )
                 )
        ),
        tabPanel("T2", value = "2",
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
)

server <-  function(input, output, session) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

shinyApp(ui, server)

# Modular version
library(shiny)
library(shinydashboard)

switcherButton <- function(id) {
  ns <- NS(id)
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1",
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3,
                       actionButton(ns("switchbutton"), "Click to switch")
                   )
                 )
        ),
        tabPanel("T2", value = "2",
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
}

switcher <- function(input, output, session, parent) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

ui <- fluidPage(
  switcherButton("switcher1")
)

server <-  function(input, output, session) {

  callModule(switcher, "switcher1")

}

shinyApp(ui, server)
</code>```

I

答: You have forgotten to wrap the tabBox id in ns(). Just replace "tabset2" by ns("tabset2")

Body:
I'm trying to modularize a shiny app that has a button to reactively switch between tabPanels using updateTabsetPanel(). This works in the non-modular app, but doesn't when making the reactive is contained in a module.  I think it has to do with the panels being outside the scope of the module.  Below are minimal examples (the non-modular version that works and the modular version that does not).  Is there a way to have the module talk to the tabPanels?

# Non-modular version
library(shiny)
library(shinydashboard)

ui <- fluidPage(
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1",
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3,
                       actionButton("switchbutton", "Click to swtich")
                   )
                 )
        ),
        tabPanel("T2", value = "2",
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
)

server <-  function(input, output, session) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

shinyApp(ui, server)

# Modular version
library(shiny)
library(shinydashboard)

switcherButton <- function(id) {
  ns <- NS(id)
  fluidRow(
    column(
      width = 12,
      tabBox(
        id = "tabset2",
        type = "tabs",
        selected = "1",
        tabPanel("T1", value = "1",
                 fluidRow(
                   box(width = 9, "Some content here"),
                   box(width = 3,
                       actionButton(ns("switchbutton"), "Click to switch")
                   )
                 )
        ),
        tabPanel("T2", value = "2",
                 fluidRow(
                   box(width = 9, "Some different content here")
                 )
        )
      )
    )
  )
}

switcher <- function(input, output, session, parent) {
  observeEvent(input$switchbutton, {
    updateTabsetPanel(session = session,
                      inputId = "tabset2",
                      selected = "2")
  })
}

ui <- fluidPage(
  switcherButton("switcher1")
)

server <-  function(input, output, session) {

  callModule(switcher, "switcher1")

}

shinyApp(ui, server)

I


问:
how to install curl for health check of spring boot jib docker image?
You define jib image in pom file, but I need curl command-line to be running on the container to do health check on aws ecs. How can I add curl into that image?</p>

答:
Alternatively, you may put curl using Jib's <extraDirectories> feature, which enables adding arbitrary files to the target image. Check the Maven and Gradle docs for more details. As explained in the docs, you will also need to configure <permissions> to set executable bits to curl.

If you prefer, you could even set up your Maven or Gradle builds to download curl and unpack it. Here's an example Jib setup (showing both Maven and Gradle) from the Jib repository.


问:
How to get a DocumentChange object for a single document from Firestore collection in Kotlin?
How can I get a DocumentChange object for a single documentSnapshot?
I want to use the type of the document's change inside my when statement. It is easy with querySnapshot, but I do not know how to get around this for a listening to changes on a single document. </p>

```<code>val uid = FirebaseAuth.getInstance().uid
val documentReference = FirebaseFirestore.getInstance().collection("users").document(uid!!)
        documentReference.addSnapshotListener{
            documentSnapshot, e ->
            when (documentSnapshot**what code needs to be here**.type) {
                DocumentChange.Type.ADDED -> {}
                DocumentChange.Type.MODIFIED -> {}
                DocumentChange.Type.REMOVED -> {}
            }
        }

</code>```

答:
You don't get a DocumentChange.Type when listening for a single document. Instead you get a DocumentSnapshot that contains the state for that document.

You can derive what happened from looking at the document, and keeping track whether this is the first callback to your listener:

```<code>if (snapshot.exists()) {
  if (isFirst) Log.i(TAG, "ADDED")
  else Log.i(TAG, "MODIFIED")
}
else {
  if (isFirst) Log.i(TAG, "NOOP")
  else Log.i(TAG, "REMOVED")
}
</code>```

Or if you prefer a flat list of conditions:

```<code>if ( snapshot.exists() &&  isFirst) Log.i(TAG, "ADDED")
if ( snapshot.exists() && !isFirst) Log.i(TAG, "MODIFIED")
if (!snapshot.exists() &&  isFirst) Log.i(TAG, "NOOP")
if (!snapshot.exists() && !isFirst) Log.i(TAG, "REMOVED")
</code>```

The NOOP is a case that would never exist in the event based listeners, as it simply wouldn't have an event for that situation.

Body:
How can I get a DocumentChange object for a single documentSnapshot?
I want to use the type of the document's change inside my when statement. It is easy with querySnapshot, but I do not know how to get around this for a listening to changes on a single document.

val uid = FirebaseAuth.getInstance().uid
val documentReference = FirebaseFirestore.getInstance().collection("users").document(uid!!)
        documentReference.addSnapshotListener{
            documentSnapshot, e ->
            when (documentSnapshot**what code needs to be here**.type) {
                DocumentChange.Type.ADDED -> {}
                DocumentChange.Type.MODIFIED -> {}
                DocumentChange.Type.REMOVED -> {}
            }
        }

Body:
You don't get a DocumentChange.Type when listening for a single document. Instead you get a DocumentSnapshot that contains the state for that document.

You can derive what happened from looking at the document, and keeping track whether this is the first callback to your listener:

if (snapshot.exists()) {
  if (isFirst) Log.i(TAG, "ADDED")
  else Log.i(TAG, "MODIFIED")
}
else {
  if (isFirst) Log.i(TAG, "NOOP")
  else Log.i(TAG, "REMOVED")
}

Or if you prefer a flat list of conditions:

if ( snapshot.exists() &&  isFirst) Log.i(TAG, "ADDED")
if ( snapshot.exists() && !isFirst) Log.i(TAG, "MODIFIED")
if (!snapshot.exists() &&  isFirst) Log.i(TAG, "NOOP")
if (!snapshot.exists() && !isFirst) Log.i(TAG, "REMOVED")

The NOOP is a case that would never exist in the event based listeners, as it simply wouldn't have an event for that situation.


问:
How to set ADODB connection property in C#
I'm trying to convert a sample for running a SQL/XML "UpdateGram" from VB to C#.

VB Example:

```<code> conn.Properties("SQLXML Version") = "SQLXML.4.0"
</code>```

C# Attempts:

```<code> conn.Properties["SQLXML Version"] = "SQLXML.4.0";
</code>```

Error: cannot be assigned, is read only.

VB Source:
https://learn.microsoft.com/en-us/sql/relational-databases/sqlxml-annotated-xsd-schemas-xpath-queries/updategrams/executing-an-updategram-by-using-ado-sqlxml-4-0?view=sql-server-ver15

答:
conn.Properties["SQLXML Version"].Value = "SQLXML.4.0";
```

That is exactly what is shown in the codes samples at that link you've mentioned.

I see where the confusion could have arrived from though, there is a purple "Notes" block that does (erroneously) contain the conn.Properties("SQLXML Version") = "SQLXML.4.0" line. This appears to be a leftover from VB6/A, where parameterless default properties were allowed. They are not allowed in VB.NET, so that line wouldn't work in VB.NET either.

Body:
I'm trying to convert a sample for running a SQL/XML "UpdateGram" from VB to C#.

VB Example:

 conn.Properties("SQLXML Version") = "SQLXML.4.0"

C# Attempts:

 conn.Properties["SQLXML Version"] = "SQLXML.4.0";

Error: cannot be assigned, is read only.

VB Source:
https://learn.microsoft.com/en-us/sql/relational-databases/sqlxml-annotated-xsd-schemas-xpath-queries/updategrams/executing-an-updategram-by-using-ado-sqlxml-4-0?view=sql-server-ver15

Body:
conn.Properties["SQLXML Version"].Value = "SQLXML.4.0";

That is exactly what is shown in the codes samples at that link you've mentioned.

I see where the confusion could have arrived from though, there is a purple "Notes" block that does (erroneously) contain the conn.Properties("SQLXML Version") = "SQLXML.4.0" line. This appears to be a leftover from VB6/A, where parameterless default properties were allowed. They are not allowed in VB.NET, so that line wouldn't work in VB.NET either.


问:
how to get a bot discord to respond on a specific text channel
I'm trying to get the bot to respond in a specific text channel, and not in the one where they wrote the message:
I tried with

case 'provino':
  message.channel.find(channel => channel.name === "provino")
```

but then I wouldn't even know how to go on; I also searched for a video but I only find people using the ID of the text channel, which I don't know how to find on Discord.

答:
You need to find the channel, like you did, and then assign the result to a new variable for further usage :</p>

```<code>case 'provino':
    const newChannel = message.guild.channels.cache.find(channel => channel.name === "provino");
    newChannel.send("Hello world.");
</code>```

Body:
I'm trying to get the bot to respond in a specific text channel, and not in the one where they wrote the message:
I tried with

case 'provino':
  message.channel.find(channel => channel.name === "provino")

but then I wouldn't even know how to go on; I also searched for a video but I only find people using the ID of the text channel, which I don't know how to find on Discord.

Body:
You need to find the channel, like you did, and then assign the result to a new variable for further usage :

case 'provino':
    const newChannel = message.guild.channels.cache.find(channel => channel.name === "provino");
    newChannel.send("Hello world.");


问:
What's wrong with this code for multiplying two matrices in C?
The aim of the matrixMultiplier function is to multiply A * B, and then show the resulting matrix C, for any two square matrices A and B. A and B sizes are limited by 10*10.

When the user is asked the size of the matrix they wish to introduce, although A and B are 10*10, the function only works with the submatrices in A and B up to the dimension which the user has specified, say 3*3.

I've tested this out multiplying the 3*3 identity matrix by itself and it's not giving me the correct answer.

#include <stdio.h>

void matrixMultiplier(int A[][10], int B[][10], int C[][10], int n) {
    int i, j, k;
    for (i = 0; i < n; i++) {
        for (k = 0; k < n; k++) {
            C[i][k] = 0;               /* Initialize output matrix to zero */
        }
    }

    for (i = 0; i < n; i++) {
        for (k = 0; k < n; k++) {
            for (j = 0; j < n; j++) {
                C[i][k] += A[i][j] * B[j][k];
            }
        }
    }
    printf("\n");

    for (i = 0; i < n; i++) {
        for (k = 0; k < n; k++) {
            printf("%4d", C[i][k]);
        }
        printf("\n");
    }
}

int main(void) {
    int A[][10] = {{0}};
    int B[][10] = {{0}};
    int C[][10] = {{0}}; /* Initialize output matrix to zero */
    int i, j;
    int n;

    printf("Enter square matrix dimension: ");
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("Assign a value: ");
            scanf("%d", &A[i][j]);
        }
        printf("New row.\n");
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%4d", A[i][j]);
        }
        printf("\n");
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("Assign a value: ");
            scanf("%d", &B[i][j]);
        }
        printf("New row.\n");
    }
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%4d", B[i][j]);
        }
        printf("\n");
    }
    matrixMultiplier(A, B, C, n);
    return 0;
}
```

答:
Take a look at this code:

```<code>#include <stdio.h>
#define MAX_SIZE 10

void matrixMultiplier(int A[][MAX_SIZE], int B[][MAX_SIZE], int C[][MAX_SIZE], int n)
{
 int i, j, k;

 for (i = 0; i < n; i++)
   for (k = 0; k < n; k++)
     for (j = 0; j < n; j++)
       C[i][k] += A[i][j] * B[j][k];

 printf("\nProduct Matrix C:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", C[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    //int A[][10] = {{0}}; By initializing like this you are creating this int A[1][10] = {{0}};
    int A[MAX_SIZE][MAX_SIZE] = {0};
    int B[MAX_SIZE][MAX_SIZE] = {0};
    int C[MAX_SIZE][MAX_SIZE] = {0};
    int i, j, n;

    printf("Enter square matrix dimension: ");
    scanf("%d", &n);

    printf("Input %d values row-wise, for matrix A: ", n*n);
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            scanf("%d", &A[i][j]);

    printf("Input %d values row-wise, for matrix B: ", n*n);
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            scanf("%d", &B[i][j]);

    printf("\nGiven Matrix A:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", A[i][j]);
        putchar('\n');
    }

    printf("\nGiven Matrix B:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", A[i][j]);
        putchar('\n');
    }

   matrixMultiplier(A, B, C, n);
   return 0;
}
</code>```

If you need more explanation about 2D arrays refer to this link

Body:
Take a look at this code:

#include <stdio.h>
#define MAX_SIZE 10

void matrixMultiplier(int A[][MAX_SIZE], int B[][MAX_SIZE], int C[][MAX_SIZE], int n)
{
 int i, j, k;

 for (i = 0; i < n; i++)
   for (k = 0; k < n; k++)
     for (j = 0; j < n; j++)
       C[i][k] += A[i][j] * B[j][k];

 printf("\nProduct Matrix C:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", C[i][j]);
        putchar('\n');
    }
}

int main(void)
{
    //int A[][10] = {{0}}; By initializing like this you are creating this int A[1][10] = {{0}};
    int A[MAX_SIZE][MAX_SIZE] = {0};
    int B[MAX_SIZE][MAX_SIZE] = {0};
    int C[MAX_SIZE][MAX_SIZE] = {0};
    int i, j, n;

    printf("Enter square matrix dimension: ");
    scanf("%d", &n);

    printf("Input %d values row-wise, for matrix A: ", n*n);
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            scanf("%d", &A[i][j]);

    printf("Input %d values row-wise, for matrix B: ", n*n);
    for(i = 0; i < n; ++i)
        for(j = 0; j < n; ++j)
            scanf("%d", &B[i][j]);

    printf("\nGiven Matrix A:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", A[i][j]);
        putchar('\n');
    }

    printf("\nGiven Matrix B:\n\n");
    for(i = 0; i < n; ++i)
    {
        for(j = 0; j < n; ++j)
            printf("%4d", A[i][j]);
        putchar('\n');
    }

   matrixMultiplier(A, B, C, n);
   return 0;
}

If you need more explanation about 2D arrays refer to this link


问:
Agora Cloud class Room Login failed

I am unable to login with agora educatuion web sdk

答:
https://docs.agora.io/en/faq/restful_authentication

Get your auth by following the instruction on that link.

go to your env.local and assign your auth to REACT_APP_AGORA_RESTFULL_TOKEN

Title: Agora Cloud class Room Login failed


问:
Javascript how to make text 10% larger
I am making a website and it is nearly finished and while testing someone mentioned a setting for text size. Now I know I can just go through and make the font to a set value that is set by something else. But I want to see if I can do it with Javascript.

On my settings page I have a range input from 80% to 120%, but how it will work is it will make the text size bigger depending on the current value it is. For example, the size setting was set to 100%, then I increased it to 110% I want all text to get 10% bigger than before, but I don't have a clue on how to do it, even if it's possible. If anyone has a different method to changing font size based on a setting that would be useful.

Or can I do this:

```<code>font-size: {{setting}};
</code>```

for the whole document after I have loaded the rest of the CSS, meaning would this set all text to this size or make it bigger/smaller depending on if its over 100%?

答:
You could change all of the text elements font sizes to be a variable, like this:

```<code>:root {
    --base-size: 10px;
}
.paragraph-here {
    font-size: var(--base-size);
}
.heading-here {
    font-size: calc(2 * var(--base-size));
}
</code>```

The --base-size variable could then be customized in an inline style in JavaScript.

Another option would be to add zoom to the entire page, like this:

```<code>body {
    zoom: 110%;
}
</code>```

This would grow the entire page though, not just the text elements.

I hope this helps.

Title: Javascript how to make text 10% larger

Body:
I am making a website and it is nearly finished and while testing someone mentioned a setting for text size. Now I know I can just go through and make the font to a set value that is set by something else. But I want to see if I can do it with Javascript.

On my settings page I have a range input from 80% to 120%, but how it will work is it will make the text size bigger depending on the current value it is. For example, the size setting was set to 100%, then I increased it to 110% I want all text to get 10% bigger than before, but I don't have a clue on how to do it, even if it's possible. If anyone has a different method to changing font size based on a setting that would be useful.

Or can I do this:

font-size: {{setting}};

for the whole document after I have loaded the rest of the CSS, meaning would this set all text to this size or make it bigger/smaller depending on if its over 100%?

Body:
You could change all of the text elements font sizes to be a variable, like this:

:root {
    --base-size: 10px;
}
.paragraph-here {
    font-size: var(--base-size);
}
.heading-here {
    font-size: calc(2 * var(--base-size));
}

The --base-size variable could then be customized in an inline style in JavaScript.

Another option would be to add zoom to the entire page, like this:

body {
    zoom: 110%;
}

This would grow the entire page though, not just the text elements.

I hope this helps.


问:
How to export the result from statsmodels test to CSV?
I am just learning how to use the statsmodels (Python module) to perform such things as regression analysis, testing for normality and homogenous variance. I am working with several data sets (usually as CSV files) and would like to write a script to help me do this more efficiently. My data is just a set of numbers.

Example of data

```<code>column1, column2
2.80609,2.80609
2.39059,1.6697286666666666
3.6487540000000003,1.8243770000000001
1.8582885714285717,3.0046419047619044
2.587834,1.7252226666666666
...
</code>```

Specifically, I would like to:

(1) Iterate a test over several files

(2) Save the result of each test to a new row in a new file

An example of one of the tests I am using.

```<code>data = pd.read_csv("data.csv")

column1 = data['column1']
p_value = sm.stats.diagnostic.lilliefors(data, dist='norm', pvalmethod='approx')
</code>```

The float it exports look like this.

```<code>(0.08557045418097009, 7.144631930303909e-50)
</code>```

My adventures into if/else and boolean values resulted in this code that prints a text that would be nifty to have exported as well.

```<code>p_value = sm.stats.diagnostic.lilliefors(curvature_length, dist='norm', pvalmethod='approx')[1]
if p_value<0.05:
    print("Data is not normal distributed")
else:
    print("Data is normal distributed")
print(p_value)
</code>```

Any tips & feedback on how to go about this would be greatly appreciated!

答:
To write the two floats to CSV https://docs.python.org/3/library/csv.html

```<code>import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    csvwriter = csv.writer(csvfile)
</code>```

cycle through the pairs of floats doing

```<code>        csvwriter.writerow([float1, float2])
</code>```

Body:
I am just learning how to use the statsmodels (Python module) to perform such things as regression analysis, testing for normality and homogenous variance. I am working with several data sets (usually as CSV files) and would like to write a script to help me do this more efficiently. My data is just a set of numbers.

Example of data

column1, column2
2.80609,2.80609
2.39059,1.6697286666666666
3.6487540000000003,1.8243770000000001
1.8582885714285717,3.0046419047619044
2.587834,1.7252226666666666
...

Specifically, I would like to:

(1) Iterate a test over several files

(2) Save the result of each test to a new row in a new file

An example of one of the tests I am using.

data = pd.read_csv("data.csv")

column1 = data['column1']
p_value = sm.stats.diagnostic.lilliefors(data, dist='norm', pvalmethod='approx')

The float it exports look like this.

(0.08557045418097009, 7.144631930303909e-50)

My adventures into if/else and boolean values resulted in this code that prints a text that would be nifty to have exported as well.

p_value = sm.stats.diagnostic.lilliefors(curvature_length, dist='norm', pvalmethod='approx')[1]
if p_value<0.05:
    print("Data is not normal distributed")
else:
    print("Data is normal distributed")
print(p_value)

Any tips & feedback on how to go about this would be greatly appreciated!

Body:
To write the two floats to CSV https://docs.python.org/3/library/csv.html

import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    csvwriter = csv.writer(csvfile)

cycle through the pairs of floats doing

        csvwriter.writerow([float1, float2])


问:
Getting error 406 from Facebooker API on Rails 2.3?
My app was working fine with Rails 2.2 and Facebooker 1.0.13, but I keep getting a 406 error with Rails 2.3.
I checked the mime type, canvas/iframe setting in Facebook, and the requests work fine outside of Facebook (i.e. I get the full app as long as I'm not accessing it within the Facebook iframe). Has something changed recently in the Facebook API that would cause this error? Or is there anything in Facebooker that you've found might be fixed quickly?

Here is my Dev log for reference:

Processing PostsController#index (for xx.xxx.xx.xxx at 2009-03-06 03:24:44) [GET]
  Parameters: {"fb_sig_app_id"=>"xxxxx",

   "fb_sig_in_iframe"=>"1",

   "fb_sig_locale"=>"en_US",
   "fb_sig_in_new_facebook"=>"1",

   "fb_sig"=>"xxxxx",

   "fb_sig_added"=>"1",

   "fb_sig_expires"=>"xxxxx",

   "fb_sig_session_key"=>"xxxxx",

   "fb_sig_ss"=>"xxxxx",

   "fb_sig_api_key"=>"xxxxx",

   "fb_sig_time"=>"1236327886.7997",

   "fb_sig_profile_update_time"=>"1228275036",

   "fb_sig_user"=>"11111"}

  User Columns (6.0ms)   SHOW FIELDS FROM users
  User Load (1.0ms)   SELECT * FROM users WHERE (users.login = 11111) LIMIT 1
  SQL (0.0ms)   BEGIN
  SQL (0.0ms)   COMMIT
  Competition Load (0.0ms)   SELECT * FROM posts

  Completed in 135ms (View: 8, DB: 8) | 406 Not Acceptable

[http://xx.xx.xxx.xxx/?fb_sig_in_iframe=1&

fb_sig_locale=en_US&

fb_sig_in_new_facebook=1&

fb_sig_time=xxxxx.xxxxx&

fb_sig_added=1&

fb_sig_profile_update_time=1228275036&

fb_sig_expires=xxxxx&

fb_sig_user=xxxxx&

...]

If more details are needed, I'll be glad to give them...:-)

答:
Found the answer in the Facebook Forums:

http://forum.developers.facebook.com/viewtopic.php?pid=93648#p93648

Sorry for implying that Facebooker wasn't working correctly...What you're doing is GREAT Michael (et al), keep up the great work!

OwnerDisplayName: btelles

ContentLicense: CC BY-SA 2.5

LastEditorDisplayName: unwind


问:
Openpyxl for cell.value and cell.internal_value error: 'int' object has no attribute 'internal_value'
I am trying to print the value of the cell in excel using openpyxl. However, I get the following error: 'int' object has no attribute 'internal_value' when I attempt to do print(cell.internal_value) and 'int' object has no attribute 'value' when I try to do print(cell.value).

I have done the following:

```<code>for cell in range(2,18):
    print(int(cell.value))
    print(cell.internal_value)
    print(cell.value)
</code>```

Any ideas?

答:
You are looping with range so cell is actually an integer and not a sheet's cell that is why you are not able to use the above attributes.

You should first try to create a new spreadsheet or load an existing one and then access its cells.

from openpyxl import load_workbook
wb = load_workbook(filename = 'name_of_your_spreadsheet.xlsx')
# Let's say you want to print the A column
for cell in wb['A2 A18']:
    print(int(cell.value)) #this might not work
    print(cell.internal_value)
    print(cell.value)
```

<p>if you want to use <code>range</code> in any case you can do something like this</p>

<pre class="lang-py prettyprint-override"><code>from openpyxl import load_workbook
wb = load_workbook(filename = 'name_of_your_spreadsheet.xlsx')
# Let's say you want to print the A column
for i in range(2,18):
    cell = ws3.cell(column=0, row=i)
    print(int(cell.value)) #this might not work
    print(cell.internal_value)
    print(cell.value)
</code>```

Body:
I am trying to print the value of the cell in excel using openpyxl. However, I get the following error: 'int' object has no attribute 'internal_value' when I attempt to do print(cell.internal_value) and 'int' object has no attribute 'value' when I try to do print(cell.value).

I have done the following:

for cell in range(2,18):
    print(int(cell.value))
    print(cell.internal_value)
    print(cell.value)

Any ideas?

Body:
You are looping with range so cell is actually an integer and not a sheet's cell that is why you are not able to use the above attributes.

You should first try to create a new spreadsheet or load an existing one and then access its cells.

from openpyxl import load_workbook
wb = load_workbook(filename = 'name_of_your_spreadsheet.xlsx')
# Let's say you want to print the A column
for cell in wb['A2 A18']:
    print(int(cell.value)) #this might not work
    print(cell.internal_value)
    print(cell.value)

if you want to use range in any case you can do something like this

from openpyxl import load_workbook
wb = load_workbook(filename = 'name_of_your_spreadsheet.xlsx')
# Let's say you want to print the A column
for i in range(2,18):
    cell = ws3.cell(column=0, row=i)
    print(int(cell.value)) #this might not work
    print(cell.internal_value)
    print(cell.value)


问:
Should I await a Firestore set call in Firebase cloud functions
Let's say I have a cloud function like this

```<code>export const setData = functions.https.onCall(async (data, context) => {
    await admin.firestore().doc("myPath").set({data: "myData"})
    return {success: true}
})
</code>```

If I don't care about the firestore set call is successful or not,
can I remove the await? So the function returns earlier and reduces CPU usage time.

```<code>export const setData = functions.https.onCall(async (data, context) => {
    admin.firestore().doc("myPath").set({data: "myData"})
    return {success: true}
})
</code>```

答:
You will have problems if you remove the await.  Without it, the function will return immediately with the return value without waiting for the set() to complete.  The function will terminate along with any asynchronous work that's not finished.

With a callable function, the function must return with a promise that resolves only after all of the async work is complete.  The await keyword makes that happen in your case.

Body:
Let's say I have a cloud function like this

export const setData = functions.https.onCall(async (data, context) => {
    await admin.firestore().doc("myPath").set({data: "myData"})
    return {success: true}
})

If I don't care about the firestore set call is successful or not,
can I remove the await? So the function returns earlier and reduces CPU usage time.

export const setData = functions.https.onCall(async (data, context) => {
    admin.firestore().doc("myPath").set({data: "myData"})
    return {success: true}
})


问:
Create my own authorization and authentication system in ASP.NET MVC
I'm working on an ASP.NET project, and i want to create and use my own authorization and authentication system to manage users (in a sql server database) like login, check authorization, and check authentication, i know in ASP.NET we have Identity but I want to create my own system.

so my question is do anyone have a good algorithm or a structure or just and idea for a custom system ?

Massive thanks in advance.

答:
You can start from simple things, creating a model of User with ordinary fields Login, Password, and AuthController that will have two methods RegisterUser and SignIn.

RegisterUser - here you have to check if Login already exists, if not - insert data to table Users. Important thing - you have to choose algorithm to encrypt user password and save it in DB.

SignIn - method that will also check if user by Login and Password exists in DB (encrypt password from request by your algorithm and check if exists the same in Users table), if he is - you have to create a token and return it in response (to give an access to your portal).

Actually we can attach to it validation to a models (see https://fluentvalidation.net/), restore password logic with email notification and so on. A lot of examples with custom features of authorization and authentication you can find in the internet. Just separate your functionality into parts and google it.


问:
API Documentation for WebRTC Android Library
I'm learning WebRTC and I have found its JavaScript documentation quiet good. But then, I want to work with webrtc on Android. So I found this page. After Adding the libraries I cannot find documentation like it is for JS. There is AppRTC but then I find it confusing rather than expressive (that might be my own problem, not sure).

So where do I go for documentation for Android WebRTC library? Is there any tutorial or simple reference that is valid as of 2020? Many data I have found are 5 or more years, and seems outdated.

答: I found very useful Github Project. Two years old as of 2020, but very informative and simple. Once you get the basics of WebRTC you can dive on the code. This works well in conjuction with WebRTC Codelab</p>


问:
Appending email to individual words in a string
The CSV looks like this: cat .\email.csv

```<code>TheName
"Adam,  Bertram,  Joe,  Jones,  Mary,  Baker"
</code>```

I'm trying to create an output that will list the name and their email address in the output.  However, the cell that contains the names, is all in one line with comma separation in the cell instead of each field.  I'm sure it's easy, but for some reason, my head isn't able to easily do this.  UGH!  Here is my attempt.  It shouldn't be complicated, right?  This is a rapidly evolving CSV and I'm unable to change that output.  Hopefully someone might have a quick fix for me?    TIA!

```<code>$NEWtmpName = @()
$emailLIST = import-csv -path email.csv
$emailLIST | foreach-object {

   $tmpName = $($_.TheName)
   write-host -f yellow $tmpName + "s email is" + $tmpName + "@microsoft.com"

}
</code>```

答:
Try something like this:</p>

```<code>$emailList = Import-CSV .\email.csv
foreach($entry in $emailList)
{
    foreach($name in $entry.TheName.Split(','))
    {
        Write-Host -f Yellow "$($name)'s email is $($name)@microsoft.com"
    }
}
</code>```

Body:
The CSV looks like this: cat .\email.csv

TheName
"Adam,  Bertram,  Joe,  Jones,  Mary,  Baker"

I'm trying to create an output that will list the name and their email address in the output.  However, the cell that contains the names, is all in one line with comma separation in the cell instead of each field.  I'm sure it's easy, but for some reason, my head isn't able to easily do this.  UGH!  Here is my attempt.  It shouldn't be complicated, right?  This is a rapidly evolving CSV and I'm unable to change that output.  Hopefully someone might have a quick fix for me?    TIA!

$NEWtmpName = @()
$emailLIST = import-csv -path email.csv
$emailLIST | foreach-object {

   $tmpName = $($_.TheName)
   write-host -f yellow $tmpName + "s email is" + $tmpName + "@microsoft.com"

}

Body:
Try something like this:

$emailList = Import-CSV .\email.csv
foreach($entry in $emailList)
{
    foreach($name in $entry.TheName.Split(','))
    {
        Write-Host -f Yellow "$($name)'s email is $($name)@microsoft.com"
    }
}


问:
Bazel compilation with a lot of different target, which are broken?
I want to compile a large set of different bazel targets  lets say [A, B, C, D] and understand which are broken.
I have notice that if I launch:
bazel build A
bazel build B
bazel build C
bazel build D

It takes a lot of time, not because of compilation time, but because of bazel setup time.

Is there an alternative solution for making this  compilation process faster, but still having the ability to understand which targets are broken and which not?

Thanks.

答:
You can do

```<code>bazel build --keep_going A B C D
</code>```

Then bazel won't stop at the first broken target, and will try to build as much as it can.

That said, if the various targets don't share a lot of the same dependencies, I wouldn't expect a huge difference, since bazel should still be caching between different invocations. Also, if you're changing build flags between invocations, then bazel may have to rerun the analysis phase (this is what I assume you mean by 'bazel setup time'). And if you need different build flags for the different targets, then you might not be able to build them all in one invocation.

Body:
You can do

bazel build --keep_going A B C D

Then bazel won't stop at the first broken target, and will try to build as much as it can.

That said, if the various targets don't share a lot of the same dependencies, I wouldn't expect a huge difference, since bazel should still be caching between different invocations. Also, if you're changing build flags between invocations, then bazel may have to rerun the analysis phase (this is what I assume you mean by 'bazel setup time'). And if you need different build flags for the different targets, then you might not be able to build them all in one invocation.


答:
Use the -replace regex operator to append the domain suffix to the end of each individual word in the input string:

```<code>Import-Csv email.csv |ForEach-Object {
  $_.TheName = $_.TheName -replace '(?<=\w\b)','@microsoft.com'
  $_
} |Export-Csv email_fixed.csv -NoTypeInformation
</code>```

Title: Appending email to individual words in a string

Body:
Use the -replace regex operator to append the domain suffix to the end of each individual word in the input string:

Import-Csv email.csv |ForEach-Object {
  $_.TheName = $_.TheName -replace '(?<=\w\b)','@microsoft.com'
  $_
} |Export-Csv email_fixed.csv -NoTypeInformation


问:
How to navigate through pages within the website using Selenium and Python
I'm scraping this website( http://rera.rajasthan.gov.in/ProjectSearch) using Python and Selenium. I have the code working but it currently only scrapes the first page, I would like to iterate through all the pages and scrape all the VIEW present in them, but they handle pagination in a weird way how would I go through the pages and scrape them one by one?

My source code:

```<code>from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, WebDriverException
import time

opt = webdriver.ChromeOptions()
opt.add_argument("--ignore-certificate-errors")
opt.add_argument("--start-maximized")

driver = webdriver.Chrome(executable_path=r"C:\Users\fit foodie\PycharmProjects\Selenium\Browser\chromedriver.exe", options=opt)

driver.get(url="http://rera.rajasthan.gov.in/")
search= driver.find_element_by_xpath("//*[@id='liSearch']/a").click()
proj_src=driver.find_element_by_xpath("//*[@id='liSearch']/ul/li[1]/a").click()

search_btn = driver.find_element_by_xpath('//*[@id="btn_SearchProjectSubmit"]').click()

def page():
    while True:
        try:
            driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(
                EC.element_to_be_clickable((By.XPATH, "//*[@id='OuterProjectGrid']/div[4]/div[4]/a"))))
            driver.find_element_by_xpath("//*[@id='OuterProjectGrid']/div[4]/div[4]/a").click()
            print("Navigating to Next Page")
        except (TimeoutException, WebDriverException) as e:
            print("Last page reached")
            break
</code>```

unable to paginate through this

img:

this is the

答:
To scrape all the resultant pages from search within the website http://rera.rajasthan.gov.in/ProjectSearch using python and Selenium you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following  Locator Strategies:

Code Block:

```<code>driver.get("http://rera.rajasthan.gov.in/ProjectSearch")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='dropdown-toggle' and contains(., 'Search')]"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='dropdown-toggle' and contains(., 'Search')]//following::ul[1]/li/a[text()='Project Search']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='btn btn-primary']"))).click()
while True:
    try:
        WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class='ds4u-footer']//div[@class='ds4u-pager']//a")))
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='ds4u-footer']//div[@class='ds4u-pager']//a[contains(@class, 'ds4u-selected')]//following::a[1]/span"))).click()
        print("Clicked for next page")
    except TimeoutException:
        print("No more pages to navigate")
        break
driver.quit()
</code>```

Console Output:

```<code>Clicked for next page
Clicked for next page
Clicked for next page
...
...
...
No more pages to navigate
</code>```

Body:
I'm scraping this website( http://rera.rajasthan.gov.in/ProjectSearch) using Python and Selenium. I have the code working but it currently only scrapes the first page, I would like to iterate through all the pages and scrape all the VIEW present in them, but they handle pagination in a weird way how would I go through the pages and scrape them one by one?

My source code:

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, WebDriverException
import time

opt = webdriver.ChromeOptions()
opt.add_argument("--ignore-certificate-errors")
opt.add_argument("--start-maximized")

driver = webdriver.Chrome(executable_path=r"C:\Users\fit foodie\PycharmProjects\Selenium\Browser\chromedriver.exe", options=opt)

driver.get(url="http://rera.rajasthan.gov.in/")
search= driver.find_element_by_xpath("//*[@id='liSearch']/a").click()
proj_src=driver.find_element_by_xpath("//*[@id='liSearch']/ul/li[1]/a").click()

search_btn = driver.find_element_by_xpath('//*[@id="btn_SearchProjectSubmit"]').click()

def page():
    while True:
        try:
            driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(
                EC.element_to_be_clickable((By.XPATH, "//*[@id='OuterProjectGrid']/div[4]/div[4]/a"))))
            driver.find_element_by_xpath("//*[@id='OuterProjectGrid']/div[4]/div[4]/a").click()
            print("Navigating to Next Page")
        except (TimeoutException, WebDriverException) as e:
            print("Last page reached")
            break

unable to paginate through this

img:

this is the

Body:
To scrape all the resultant pages from search within the website http://rera.rajasthan.gov.in/ProjectSearch using python and Selenium you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following  Locator Strategies:

Code Block:

driver.get("http://rera.rajasthan.gov.in/ProjectSearch")
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='dropdown-toggle' and contains(., 'Search')]"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='dropdown-toggle' and contains(., 'Search')]//following::ul[1]/li/a[text()='Project Search']"))).click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='btn btn-primary']"))).click()
while True:
    try:
        WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[@class='ds4u-footer']//div[@class='ds4u-pager']//a")))
        WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='ds4u-footer']//div[@class='ds4u-pager']//a[contains(@class, 'ds4u-selected')]//following::a[1]/span"))).click()
        print("Clicked for next page")
    except TimeoutException:
        print("No more pages to navigate")
        break
driver.quit()

Console Output:

Clicked for next page
Clicked for next page
Clicked for next page
...
...
...
No more pages to navigate


问:
Does the restore force re-index the db for new custom dictionary index in the destination DB?
Let's say source DB don't have custom dictionary index.

I added the customer dictionary index to the destination DB.

Now the question is after restoring do I need to force re-indexing the db for custom dictionary or it will automatically re-index the db?

答:
I'm not sure if it will force a reindex, but if you change the custom dictionary you should reindex the data, as it will affect the stemming and tokenization:

https://docs.marklogic.com/guide/search-dev/custom-dictionaries#id_42767

You should reindex if you change a custom dictionary.


问:
Add values to MatOfPoint variable in Java
I'm trying to convert a double[][] into a MatOfPoint of OpenCV. pointsOrdered is a double[4][2] with coordinates of four points in it.
I've tried with:

```<code>MatOfPoint sourceMat =  new MatOfPoint();
for (int idx = 0; idx < 4; idx++) {
    (sourceMat.get(idx, 0))[0] = pointsOrdered[idx][0];
    (sourceMat.get(idx, 0))[1] = pointsOrdered[idx][1];
}
</code>```

but sourceMat values stay the same.
I'm trying to add values one by one as I haven't found other options.

What can I do? Is there a simple way to access and modify a MatOfPoint variable values?

答:
Here's an excessively complicated example answer to show what can be done that combines the use of lists/arrays/array lists (pick your poison) as recommended with what is really wrong and caused the question.  "Mat get" method and "Mat put" method had been confused - reversed in usage.

MatOfPoint sourceMat=new MatOfPoint();

sourceMat.fromArray( // a recommended way to initialize at compile time if you know the values
                new Point(151., 249.),
                new Point(105., 272.),
                new Point(102., 318.),
                new Point(138., 337.));

// A way to change existing data or put new data if need be if you set the size of the MatOfPoints first
double[] corner=new double[(int)(sourceMat.channels())];// 2 channels for a point

for (int idx = 0; idx<sourceMat.rows(); idx++) {
     System.out.println((corner[0]=sourceMat.get(idx, 0)[0]) + ", " + (corner[1]=sourceMat.get(idx, 0)[1]));
     corner[0]+=12.; // show some change can be made to existing point.x
     corner[1]+=8.; // show some change can be made to existing point.y
     sourceMat.put(idx, 0, corner);
     System.out.println((corner[0]=(float)sourceMat.get(idx, 0)[0]) + ", " + (corner[1]=(float)sourceMat.get(idx, 0)[1]));
}
```

Body:
I'm trying to convert a double[][] into a MatOfPoint of OpenCV. pointsOrdered is a double[4][2] with coordinates of four points in it.
I've tried with:

MatOfPoint sourceMat =  new MatOfPoint();
for (int idx = 0; idx < 4; idx++) {
    (sourceMat.get(idx, 0))[0] = pointsOrdered[idx][0];
    (sourceMat.get(idx, 0))[1] = pointsOrdered[idx][1];
}

but sourceMat values stay the same.
I'm trying to add values one by one as I haven't found other options.

What can I do? Is there a simple way to access and modify a MatOfPoint variable values?


问:
Not creating txt file in c drive by file operations in C language
I am trying to create a simple text file using TurboC++ DOS emulator. But, it's not creating the file. I am referring to an online video where the same file is getting created. What can be the issue?

Below is the code:

```<code>#include<stdio.h>
#include<stdlib.h>

int main()
{
  int num;
  FILE *fptr;

  fptr = fopen("c:\\program.txt","w");

  if(fptr == NULL)
  {
    printf("error");
    exit(1);
  }
  printf("enter num = ");
  scanf("%d", &num);

  fprintf(fptr,"%d",num);
  fclose(fptr);

  return 0;

}
</code>```

答:
Go to the prompt in the DOS emulator and do something like DIR > C:\program.txt, check if you get an error and if not then check with DIR C:\ if that file is actually created.

If that doesn't work it's not a problem with your C application, but with the possibility to write there (like file access rights or a read-only drive).

Body:
I am trying to create a simple text file using TurboC++ DOS emulator. But, it's not creating the file. I am referring to an online video where the same file is getting created. What can be the issue?

Below is the code:

#include<stdio.h>
#include<stdlib.h>

int main()
{
  int num;
  FILE *fptr;

  fptr = fopen("c:\\program.txt","w");

  if(fptr == NULL)
  {
    printf("error");
    exit(1);
  }
  printf("enter num = ");
  scanf("%d", &num);

  fprintf(fptr,"%d",num);
  fclose(fptr);

  return 0;

}