问:
swift notification not triggering
I'm new to notifications in swift and have setup the following in my AppDelegate.swift file. It runs and I get print output that the notifications are setup and do not error. I also get the permission ask for notifications, which I click yes to. I believe the interval notification I have should trigger in 20 seconds after launch. It does not trigger, this doesn't change if I'm in the app or have minimized the app. Note I am running in Simulator mode from XCODE. Why is my notification not triggering?</p>

```<code>    func setupNotifications(){

        let notificationCenter = UNUserNotificationCenter.current()

        notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if granted {
                print("Yay!")
            } else {
                print("D'oh")
            }
        }

        notificationCenter.removeAllPendingNotificationRequests()
        print("setting up notifications")
        let content = UNMutableNotificationContent()
        content.title = "Answer your daily questions"
        content.body = "Answer your daily questions please"
        content.categoryIdentifier = "alarm"
        content.userInfo = ["customData": "fizzbuzz"]
        content.sound = UNNotificationSound.default

        //let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (1*60), repeats: true)
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 20, repeats: false)

        // Create the request
        let request = UNNotificationRequest(identifier: "daily-notifier",
                    content: content, trigger: trigger)

        // Schedule the request with the system.
        notificationCenter.add(request) { (error) in
           if error != nil {
            print("there were errors to address")
              // Handle any errors.
           }
        }
        print("done setting up notifications")
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let path = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
        print("\(path)")

        // Override point for customization after application launch.

        setupNotifications()
        return true
    }
</code>```

答:
First note that you should probably wait to receive permission before adding a request for a local notification as per Apple's documentation of the requestAuthorization(options:completionHandler:)

Note: Always call this method before scheduling any local notifications and before registering with the Apple Push Notification service.

Also make sure that you've added Push Notifications as a capability for your app as this will be needed should you submit it.

After I ran the above code I did not receive a notification while the app was still active but I did receive one while the app was in the background. I believe that if a user receives a notification for an app that is in the active state it is given silently; i.e., without the banner and sound (at least this is what I have experienced with my notifications, although there may be more to it).

Title: swift notification not triggering

Body:
I'm new to notifications in swift and have setup the following in my AppDelegate.swift file. It runs and I get print output that the notifications are setup and do not error. I also get the permission ask for notifications, which I click yes to. I believe the interval notification I have should trigger in 20 seconds after launch. It does not trigger, this doesn't change if I'm in the app or have minimized the app. Note I am running in Simulator mode from XCODE. Why is my notification not triggering?

    func setupNotifications(){

        let notificationCenter = UNUserNotificationCenter.current()

        notificationCenter.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if granted {
                print("Yay!")
            } else {
                print("D'oh")
            }
        }

        notificationCenter.removeAllPendingNotificationRequests()
        print("setting up notifications")
        let content = UNMutableNotificationContent()
        content.title = "Answer your daily questions"
        content.body = "Answer your daily questions please"
        content.categoryIdentifier = "alarm"
        content.userInfo = ["customData": "fizzbuzz"]
        content.sound = UNNotificationSound.default

        //let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (1*60), repeats: true)
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 20, repeats: false)

        // Create the request
        let request = UNNotificationRequest(identifier: "daily-notifier",
                    content: content, trigger: trigger)

        // Schedule the request with the system.
        notificationCenter.add(request) { (error) in
           if error != nil {
            print("there were errors to address")
              // Handle any errors.
           }
        }
        print("done setting up notifications")
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        let path = NSSearchPathForDirectoriesInDomains(.applicationSupportDirectory, .userDomainMask, true)
        print("\(path)")

        // Override point for customization after application launch.

        setupNotifications()
        return true
    }


来源: stackexchange

问:
Check if PHP session_id is in use
I am building a web-app that users can upload certain files and work on them through the web-app interface. I need to store these files for the length of a users session. I am creating a folder for each user using the session_id  as the folder name and storing the files in there.

The problem: There is nothing to indicate that a user walked away from my site and the session is going out of use. I need a cleanup script that takes the name of each folder and checks if that session_id is still active in order to delete unused and now unreachable folders. How can I do this?

答:
The problem you have is basically the same problem (on a less complex level) that occurs when you have got a custom session file directory. You need to clean it up yourself as well. The process is also known as garbage collection.

This is normally done by having a janitor job running on the server side that checks for outdated session files, or in your example, for outdated session directories (this can be a cron job).

This is how it works:

Most file-systems store the creation and last access date of a file. So if a session times out it has not been used any longer for X hours. So you can safely assume that if a session file has not been accessed within the last X hours that the session is dead and all files "older" than this amount of time can be safely deleted.

Job done. For your directory you might want to add a file inside you'd like to use as a testfile to track access time.

The php manual has some examples of that: http://www.php.net/manual/en/session.configuration.php#ini.session.save-path (look for the mod_files.sh script)

ContentLicense: CC BY-SA 3.0

Title: Check if PHP session_id is in use


问:
How to place multiple invisible links over one picture in html?
I am making a website using flask and want an image where clicking different parts of this will take you to different links. Is this possible? Even somewhere I could start figuring out something like this would be great thanks!</p>

答: Regardless of the back end you use (Flask or otherwise), you are looking for an HTML image map - a well established concept since the early days of the web.</p>

ContentLicense: CC BY-SA 4.0


问:
How to click an element that is blocked in protractor?
Im trying to click a button but sometimes a pop up gets in front of this button, and my automation script fails telling me the element is intercepted and not clickable, I have a function to scroll down to the element, but still this other element gets in front, is there a way to workaround this blocking element?

I can try actions, but this will not work in FireFox as in protactor its not supported, any ideas how to create a function to "Round" the element to make sure no other element is blocking it?

答:
First of all, direct answer to your question. Use this java scrip click

```<code>/**
*  Clicks on passed element by injecting js click() in the context of window
*  @param    {ElementFinder}      $element       Locator of element
*  @return   {Promise}
*/
let jsClick = $element =>
        return browser.executeScript(
            'arguments[0].click();', $element.getWebElement()
        );
</code>```

What it does - when you call the function and pass an element, it injects a js code into browser's console. this code locates your element and performs a click. Important difference that it will click the element regardless of layout or it's visibility, so don't overuse it in tests, because it's not really a user-like behavior

Also, what element blocks your button? I've had this many times, when a third party integration brings up some random popups, and you don't have a control over those elements. What I did, and it always worked, I was removing that integration also by injecting some code in browser. But the code is different for all of them, so you'll need to research this. Example is here
https://stackoverflow.com/a/59039308/9150146

Body:
First of all, direct answer to your question. Use this java scrip click

/**
*  Clicks on passed element by injecting js click() in the context of window
*  @param    {ElementFinder}      $element       Locator of element
*  @return   {Promise}
*/
let jsClick = $element =>
        return browser.executeScript(
            'arguments[0].click();', $element.getWebElement()
        );

What it does - when you call the function and pass an element, it injects a js code into browser's console. this code locates your element and performs a click. Important difference that it will click the element regardless of layout or it's visibility, so don't overuse it in tests, because it's not really a user-like behavior

Also, what element blocks your button? I've had this many times, when a third party integration brings up some random popups, and you don't have a control over those elements. What I did, and it always worked, I was removing that integration also by injecting some code in browser. But the code is different for all of them, so you'll need to research this. Example is here
https://stackoverflow.com/a/59039308/9150146


问:
How do I get around initializing variables inside init() if they are initialized by loading .json data?
I have a struct PrimaryUser() whose variables get loaded in through a .json file parser. One of those variables are a date string in the ISO8601 format. I want to have that value automatically converted to a Date type variable.

The problem I'm facing is that I don't know how to make this code run automatically upon creation of PrimaryUser():

```<code>        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        self.dateOfBirth = dateFormatter.date(from: dateOfBirthISO8601)!
</code>```

If I put this code inside init(), I get the error:

```<code>'self' used before all stored properties are initialized
</code>```

If I try making dateOfBirth a lazy variable, I run into this error:

```<code>Lazy properties must have an initializer
</code>```

Again to reiterate, all the PrimaryUser() variables will be initialized with data from a .json file through a parser that's totally separate from PrimaryUser(). So it doesn't make sense to initialize the variables inside PrimaryUser().

Here's what PrimaryUser() looks like:

```<code>import Foundation
import SwiftUI

struct PrimaryUser: User, Hashable, Codable, Identifiable {
    var id: Int
    var firstName: String
    var lastName: String
    var dateOfBirthISO8601: String
    lazy var dateOfBirth: Date
    init() {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        self.dateOfBirth = dateFormatter.date(from: dateOfBirthISO8601)!
    }
}
</code>```

答:
You can initiate lazy like this</p>

```<code>struct PrimaryUser:  Hashable, Codable, Identifiable {
    var id: Int
    var firstName: String
    var lastName: String
    var dateOfBirthISO8601: String
    lazy var dateOfBirth: Date? = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        let date  = dateFormatter.date(from: dateOfBirthISO8601)
        return date
    }()
}
</code>```

Body:
I have a struct PrimaryUser() whose variables get loaded in through a .json file parser. One of those variables are a date string in the ISO8601 format. I want to have that value automatically converted to a Date type variable.

The problem I'm facing is that I don't know how to make this code run automatically upon creation of PrimaryUser():

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        self.dateOfBirth = dateFormatter.date(from: dateOfBirthISO8601)!

If I put this code inside init(), I get the error:

'self' used before all stored properties are initialized

If I try making dateOfBirth a lazy variable, I run into this error:

Lazy properties must have an initializer

Again to reiterate, all the PrimaryUser() variables will be initialized with data from a .json file through a parser that's totally separate from PrimaryUser(). So it doesn't make sense to initialize the variables inside PrimaryUser().

Here's what PrimaryUser() looks like:

import Foundation
import SwiftUI

struct PrimaryUser: User, Hashable, Codable, Identifiable {
    var id: Int
    var firstName: String
    var lastName: String
    var dateOfBirthISO8601: String
    lazy var dateOfBirth: Date
    init() {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        self.dateOfBirth = dateFormatter.date(from: dateOfBirthISO8601)!
    }
}

Body:
You can initiate lazy like this

struct PrimaryUser:  Hashable, Codable, Identifiable {
    var id: Int
    var firstName: String
    var lastName: String
    var dateOfBirthISO8601: String
    lazy var dateOfBirth: Date? = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
        let date  = dateFormatter.date(from: dateOfBirthISO8601)
        return date
    }()
}


问:
Read large files - 2GB+ for Google Drive API Upload
I'm currently working on a small backup tool written in C# that is supposed to upload files contained within a specified folder to Google Drive via its API. The program largely functions as it's supposed to, the only problem that it is unable to handle files larger than 2GB.

The problem is caused by the upload function itself which is attached down below, it uses a byte array to read the file to subsequently create a Memory Stream. As far as I'm aware (I'm still a beginner when it comes to c#), a byte array can only contain 2GB of information before returning an overflow exception. To combat this I've tried to utilize FileStream.Read (second bit of code attached below) instead of System.IO.File.ReadAllBytes, though this again lead to an overflow exception of the byte Array. I know that at this point I'd have to split the file up, however, due to the rather limited documentation of the GDrive API for C# - at least from what I've seen - and my limited knowledge of C# I've got little to no clue on how to tackle this problem.

I'm sorry for the long read, all help on this matter is highly appreciated.

Upload Function V1 (System.IO.File.ReadAllBytes):

```<code>    private static Google.Apis.Drive.v3.Data.File UploadFile(Boolean useFolder, String mime, DriveService _service, string _uploadFile, string _parent, string _descrp = "")
    {
        if (System.IO.File.Exists(_uploadFile))
        {
            Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File
            {
                Name = System.IO.Path.GetFileName(_uploadFile),
                Description = _descrp,
                MimeType = mime
            };
            if (useFolder)
            {
                body.Parents = new List<string> { _parent };
            }
            byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
            MemoryStream stream = new System.IO.MemoryStream(byteArray);
            try
            {
                FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, mime);
                request.SupportsTeamDrives = true;
                request.Upload();
                return request.ResponseBody;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error Occured: " + e);
                return null;
            }
        }
        else
        {
            Console.WriteLine("The file does not exist. 404");
            return null;
        }
    }
</code>```

Upload Method V2 (FileStream):

```<code>    private static Google.Apis.Drive.v3.Data.File UploadFile(Boolean useFolder, String mime, DriveService _service, string _uploadFile, string _parent, string _descrp = "")
    {
        if (System.IO.File.Exists(_uploadFile))
        {
            Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File
            {
                Name = System.IO.Path.GetFileName(_uploadFile),
                Description = _descrp,
                MimeType = mime
            };
            if (useFolder)
            {
                body.Parents = new List<string> { _parent };
            }
            //byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
            using (FileStream fileStream = new FileStream(_uploadFile, FileMode.Open, FileAccess.Read))
            {
                Console.WriteLine("ByteArrayStart");
                byte[] byteArray = new byte[fileStream.Length];
                int bytesToRead = (int)fileStream.Length;
                int bytesRead = 0;
                while (bytesRead > 0)
                {
                    int n = fileStream.Read(byteArray, bytesRead, bytesToRead);
                    if (n == 0)
                    {
                        break;
                    }
                    bytesRead += n;
                    Console.WriteLine("Bytes Read: " + bytesRead);
                    bytesToRead -= n;
                    Console.WriteLine("Bytes to Read: " + bytesToRead);
                }
                bytesToRead = byteArray.Length;
                MemoryStream stream = new System.IO.MemoryStream(byteArray);
                try
                {
                    FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, mime);
                    request.SupportsTeamDrives = true;
                    request.Upload();
                    return request.ResponseBody;
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error Occured: " + e);
                    return null;
                }
            }
        }
        else
        {
            Console.WriteLine("The file does not exist. 404");
            return null;
        }
    }
</code>```

答:
MemoryStream's constructors only work with byte arrays that are limited to Int32.MaxValue bytes.  Why not just use your FileStream object directly?

```<code>var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
    Name = "flag.jpg"
};

FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(@"C:\temp\flag.jpg", System.IO.FileMode.Open))
{
    request = service.Files.Create(fileMetadata, stream, "image/jpeg");
    request.Fields = "id";
    request.Upload();
}
var file = request.ResponseBody;
</code>```

Really a file that big you should be using resumable upload but im going to have to dig around for some sample code for that.

Body:
I'm currently working on a small backup tool written in C# that is supposed to upload files contained within a specified folder to Google Drive via its API. The program largely functions as it's supposed to, the only problem that it is unable to handle files larger than 2GB.

The problem is caused by the upload function itself which is attached down below, it uses a byte array to read the file to subsequently create a Memory Stream. As far as I'm aware (I'm still a beginner when it comes to c#), a byte array can only contain 2GB of information before returning an overflow exception. To combat this I've tried to utilize FileStream.Read (second bit of code attached below) instead of System.IO.File.ReadAllBytes, though this again lead to an overflow exception of the byte Array. I know that at this point I'd have to split the file up, however, due to the rather limited documentation of the GDrive API for C# - at least from what I've seen - and my limited knowledge of C# I've got little to no clue on how to tackle this problem.

I'm sorry for the long read, all help on this matter is highly appreciated.

Upload Function V1 (System.IO.File.ReadAllBytes):

    private static Google.Apis.Drive.v3.Data.File UploadFile(Boolean useFolder, String mime, DriveService _service, string _uploadFile, string _parent, string _descrp = "")
    {
        if (System.IO.File.Exists(_uploadFile))
        {
            Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File
            {
                Name = System.IO.Path.GetFileName(_uploadFile),
                Description = _descrp,
                MimeType = mime
            };
            if (useFolder)
            {
                body.Parents = new List<string> { _parent };
            }
            byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
            MemoryStream stream = new System.IO.MemoryStream(byteArray);
            try
            {
                FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, mime);
                request.SupportsTeamDrives = true;
                request.Upload();
                return request.ResponseBody;
            }
            catch (Exception e)
            {
                Console.WriteLine("Error Occured: " + e);
                return null;
            }
        }
        else
        {
            Console.WriteLine("The file does not exist. 404");
            return null;
        }
    }

Upload Method V2 (FileStream):

    private static Google.Apis.Drive.v3.Data.File UploadFile(Boolean useFolder, String mime, DriveService _service, string _uploadFile, string _parent, string _descrp = "")
    {
        if (System.IO.File.Exists(_uploadFile))
        {
            Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File
            {
                Name = System.IO.Path.GetFileName(_uploadFile),
                Description = _descrp,
                MimeType = mime
            };
            if (useFolder)
            {
                body.Parents = new List<string> { _parent };
            }
            //byte[] byteArray = System.IO.File.ReadAllBytes(_uploadFile);
            using (FileStream fileStream = new FileStream(_uploadFile, FileMode.Open, FileAccess.Read))
            {
                Console.WriteLine("ByteArrayStart");
                byte[] byteArray = new byte[fileStream.Length];
                int bytesToRead = (int)fileStream.Length;
                int bytesRead = 0;
                while (bytesRead > 0)
                {
                    int n = fileStream.Read(byteArray, bytesRead, bytesToRead);
                    if (n == 0)
                    {
                        break;
                    }
                    bytesRead += n;
                    Console.WriteLine("Bytes Read: " + bytesRead);
                    bytesToRead -= n;
                    Console.WriteLine("Bytes to Read: " + bytesToRead);
                }
                bytesToRead = byteArray.Length;
                MemoryStream stream = new System.IO.MemoryStream(byteArray);
                try
                {
                    FilesResource.CreateMediaUpload request = _service.Files.Create(body, stream, mime);
                    request.SupportsTeamDrives = true;
                    request.Upload();
                    return request.ResponseBody;
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error Occured: " + e);
                    return null;
                }
            }
        }
        else
        {
            Console.WriteLine("The file does not exist. 404");
            return null;
        }
    }

Body:
MemoryStream's constructors only work with byte arrays that are limited to Int32.MaxValue bytes.  Why not just use your FileStream object directly?

var fileMetadata = new Google.Apis.Drive.v3.Data.File()
{
    Name = "flag.jpg"
};

FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream(@"C:\temp\flag.jpg", System.IO.FileMode.Open))
{
    request = service.Files.Create(fileMetadata, stream, "image/jpeg");
    request.Fields = "id";
    request.Upload();
}
var file = request.ResponseBody;

Really a file that big you should be using resumable upload but im going to have to dig around for some sample code for that.


问:
AWS Cloudfront can't access S3 files deployed with CodeBuild
I'm working on getting a static website deployed with AWS Codebuild, hosted in an S3 bucket, and accessed via Cloudfront. Everything seems to work except from accessing from Cloudfront. From Cloudfront, I can access files that I manually upload, and using the bucket URL, I can access all the files. Looking through the individual file settings/permissions, they all look to be the same, regardless of whether they were manually uploaded, or deployed via Codebuild. I've tried invalidating the Cloudfront cache, and re-deployed via Codebuild several times.

Additional Information:

I provided the S3 bucket as an origin when setting up the Cloudfront distribution.

Accessing via Cloudfront gives the following error:

```<code><Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>0211CBE618946F</RequestId>
<HostId>
7sRZhaJS4x2W7Iaeo4y8KAjvsOJcNWh3PxCdgnhXPE22oyp1RxZhwpjrqbsWapsUSaqBK+jqE=
</HostId>
</Error>
</code>```

What else should I check?

答:
For some reason, adding a default root object fixed the issue.

FWIW, I initially changed the value to dist/index.html, which allowed me to access the deployed bucket contents via the Cloudfront URL, but required the index.html suffix. Once I changed it to index.html, everything worked fine.

Body:
I'm working on getting a static website deployed with AWS Codebuild, hosted in an S3 bucket, and accessed via Cloudfront. Everything seems to work except from accessing from Cloudfront. From Cloudfront, I can access files that I manually upload, and using the bucket URL, I can access all the files. Looking through the individual file settings/permissions, they all look to be the same, regardless of whether they were manually uploaded, or deployed via Codebuild. I've tried invalidating the Cloudfront cache, and re-deployed via Codebuild several times.

Additional Information:

I provided the S3 bucket as an origin when setting up the Cloudfront distribution.

Accessing via Cloudfront gives the following error:

<Error>
AccessDenied
<Message>Access Denied</Message>
<RequestId>0211CBE618946F</RequestId>
<HostId>
7sRZhaJS4x2W7Iaeo4y8KAjvsOJcNWh3PxCdgnhXPE22oyp1RxZhwpjrqbsWapsUSaqBK+jqE=
</HostId>
</Error>

What else should I check?


问:
How do I batch sql statements with package database/sql
How do I batch sql statements with Go's database/sql package?

In Java I would do it like this :

```<code>// Create a prepared statement
String sql = "INSERT INTO my_table VALUES(?)";
PreparedStatement pstmt = connection.prepareStatement(sql);

// Insert 10 rows of data
for (int i=0; i<10; i++) {
    pstmt.setString(1, ""+i);
    pstmt.addBatch();
}

// Execute the batch
int [] updateCounts = pstmt.executeBatch();
</code>```

How would I achieve the same in Go?

答:
I got pq.CopyIn working, and it's actually 2.4x faster than the string values/args approach (which was super helpful and an elegant solution, btw, so thank you!)

I inserted 10 million test values of int, varchar into a struct, and loaded it with the following function. I'm kinda new to GoLang, so bear with me ...

```<code>func copyData(client *client.DbClient, dataModels []*dataModel) error{
    db := *client.DB
    txn, err := db.Begin()
    if err != nil {
        return err
    }
    defer txn.Commit()

    stmt, err := txn.Prepare(pq.CopyIn("_temp", "a", "b"))
    if err != nil {
        return(err)
    }

    for _, model := range dataModels{
        _, err := stmt.Exec(model.a, model.b)
        if err != nil {
            txn.Rollback()
            return err
        }
    }

    _, err = stmt.Exec()
    if err != nil {
        return err
    }

    err = stmt.Close()
    if err != nil {
        return err
    }

    return nil
    }
</code>```

`

Elapsed (stringValues/args): 1m30.60s.

Elapsed (copyIn): 37.57s.

Body:
How do I batch sql statements with Go's database/sql package?

In Java I would do it like this :

// Create a prepared statement
String sql = "INSERT INTO my_table VALUES(?)";
PreparedStatement pstmt = connection.prepareStatement(sql);

// Insert 10 rows of data
for (int i=0; i<10; i++) {
    pstmt.setString(1, ""+i);
    pstmt.addBatch();
}

// Execute the batch
int [] updateCounts = pstmt.executeBatch();

How would I achieve the same in Go?

Body:
I got pq.CopyIn working, and it's actually 2.4x faster than the string values/args approach (which was super helpful and an elegant solution, btw, so thank you!)

I inserted 10 million test values of int, varchar into a struct, and loaded it with the following function. I'm kinda new to GoLang, so bear with me ...

func copyData(client *client.DbClient, dataModels []*dataModel) error{
    db := *client.DB
    txn, err := db.Begin()
    if err != nil {
        return err
    }
    defer txn.Commit()

    stmt, err := txn.Prepare(pq.CopyIn("_temp", "a", "b"))
    if err != nil {
        return(err)
    }

    for _, model := range dataModels{
        _, err := stmt.Exec(model.a, model.b)
        if err != nil {
            txn.Rollback()
            return err
        }
    }

    _, err = stmt.Exec()
    if err != nil {
        return err
    }

    err = stmt.Close()
    if err != nil {
        return err
    }

    return nil
    }

`

Elapsed (stringValues/args): 1m30.60s.

Elapsed (copyIn): 37.57s.


问:
Can I edit the context menu of a text field (not Explorer context menu)?
I want to add an entry to the context menu of a text field, eg:

I have an AutoHotkey executable that will put highlighted text into the clipboard, then execute a Google search in Chrome with the clipboard. I would like a registry addition that gives me a single-click in the menu, that runs that executable. I have achieved this in the Explorer context menu (for processing of files with third-party applications, etc), but I have found no mention anywhere of the ability to change this specific menu.

答:
;Menu Google Search Autohotkey script: select any text in any text edit field, then press
AppsKey & RButton::
^+g:: ; or press Ctrl+Shift+g
Menu,GoogleSearch,Add,Search with Google,GoogleSearch
Menu,GoogleSearch,Show
return

GoogleSearch:
{
Send, ^c
Sleep 50
Run, http://www.google.com/search?q=%clipboard%
Return
}


问:
Stack DIVs or Table Columns on mobile - HTML and inline CSS only, no stylesheet or media queries
this is a bit of an annoying one.

I'm editing HTML blocks on a Moodle site (a bit like editing content on Wordpress, but with no styling options - HTML only!) - it doesn't allow me to add any CSS. Every time I do, it deletes it upon saving my edit.

So... I've been trying for a while (and I'm not great at web coding btw!) to create a standard menu block using either a table or divs. I want them to fit 100% width and then stack when on mobile. Text in each block needs to be responsive as well.

I've been trying with inline CSS, using display:inline-block, but it never works... Don't really udnerstand how the display thing works tbh.

Here's my code so far - apologies, I'm not a coder - did html once decades ago!

Any help, much appreciated. Remember no CSS sheet or Media Queries - pure HTMl and inline CSS only.. Sigh...

```<code>    <div style=width:100%; height: auto; display:inline-block";>
        <div style="width: 23%; text-align: center; display: inline-block; align: left; background-color: #ffdd00; height: 40px; padding-left:50";>

<h style="width: 25%; height: 35";><a href="https://blabla.com" style="text-decoration: none;"><strong><span style="font-family: arial, helvetica, sans-serif; font-size: 2vw;">home</span></strong></a></h>
</div>

<div style="width: 25%; text-align: center; display: inline-block; align: left; background-color: #ffdd00; height: 40px; padding-left:50";>

<h style="width: 25%; height: 35";><a href="https://blabla.com" style="text-decoration: none;"><strong><span style="font-family: arial, helvetica, sans-serif; font-size: 2vw;">home</span></strong></a></h>
</div>

<div style="width: 23%; text-align: center; display: inline-block; align: left; background-color: #ffdd00; height: 40px";>

<h style="width: 23%; height: 35";><a href="https://blabla.com" style="text-decoration: none;"><strong><span style="font-family: arial, helvetica, sans-serif; font-size: 2vw;">home</span></strong></a></h>
</div>

<div style="width: 23%; text-align: center; display: inline-block; align: left; background-color: #ffdd00; height: 40px";>

<h style="width: 23%; height: 35";><a href="https://blabla.com" style="text-decoration: none;"><strong><span style="font-family: arial, helvetica, sans-serif; font-size: 2vw;">home</span></strong></a></h>
</div>
</div>
</code>```

答:
Happy days. Let us get a few things cleared up:

At this moment you have a container of 100% width, containing a div of 23% width, with an h that is 23% wide, meaning that h is only 23% of 23% wide. I would suggest removing the width of this h.

Also: <h> doesn't exist.
,
...
 do. Use these, and mark these up accordingly. If that becomes too ugly, only leave the anchor tag with that span inside.

There are errors in your code. ";> is an invalid way of closing tags. Use ;"> instead.

align:left; doesn't work in general in the intended way.

To get to answer: while using 23% as a width, that means that you always try to fit these elements at a 23% width inside the container and that will not wrap (it will try cramming them all in). It will, as far as I know, not be possible though to achieve a perfectly responsive result without using media-queries. You can, however try setting a min-width in the four divs, with a fixed value, like 320px or so (notice they still need to fit on a mobile device). Then it will have to wrap. Additionally, you could play around with text-align, margin:auto. Bonus: try replacing display:inline-block with float:left; as that will remove the spaces between the elements. Notice that the markup might fail, and in that case add

 at the bottom of that container-div.

Body:
this is a bit of an annoying one.

I'm editing HTML blocks on a Moodle site (a bit like editing content on Wordpress, but with no styling options - HTML only!) - it doesn't allow me to add any CSS. Every time I do, it deletes it upon saving my edit.

So... I've been trying for a while (and I'm not great at web coding btw!) to create a standard menu block using either a table or divs. I want them to fit 100% width and then stack when on mobile. Text in each block needs to be responsive as well.

I've been trying with inline CSS, using display:inline-block, but it never works... Don't really udnerstand how the display thing works tbh.

Here's my code so far - apologies, I'm not a coder - did html once decades ago!

Any help, much appreciated. Remember no CSS sheet or Media Queries - pure HTMl and inline CSS only.. Sigh...

<h style="width: 25%; height: 35";>home</h>

<h style="width: 25%; height: 35";>home</h>

<h style="width: 23%; height: 35";>home</h>

<h style="width: 23%; height: 35";>home</h>

Body:
Happy days. Let us get a few things cleared up:

At this moment you have a container of 100% width, containing a div of 23% width, with an h that is 23% wide, meaning that h is only 23% of 23% wide. I would suggest removing the width of this h.

Also: <h> doesn't exist. <h1>, <h2>... <h6> do. Use these, and mark these up accordingly. If that becomes too ugly, only leave the anchor tag with that span inside.

There are errors in your code. ";> is an invalid way of closing tags. Use ;"> instead.

align:left; doesn't work in general in the intended way.

To get to answer: while using 23% as a width, that means that you always try to fit these elements at a 23% width inside the container and that will not wrap (it will try cramming them all in). It will, as far as I know, not be possible though to achieve a perfectly responsive result without using media-queries. You can, however try setting a min-width in the four divs, with a fixed value, like 320px or so (notice they still need to fit on a mobile device). Then it will have to wrap. Additionally, you could play around with text-align, margin:auto. Bonus: try replacing display:inline-block with float:left; as that will remove the spaces between the elements. Notice that the markup might fail, and in that case add <div style="clear:both;"></div> at the bottom of that container-div.


问:
Property 'controls' does not exist on type 'AbstractControl' - angular8
In Component I Have

```<code>  @Input() CaseFormIn: FormGroup;
get f() { return this.CaseFormIn.controls; }
</code>```

In Template

```<code> <div class="error-message" *ngIf="this.f.generalInfoFormGroup.controls.primaryStore.touched&&this.f.generalInfoFormGroup.controls.primaryStore.errors">
           Primary Store is a Required Field.
        </div>
</code>```

in development code is working fine but getting below error in prod mode
 Property 'controls' does not exist on type 'AbstractControl'.

答:
try it

```<code>get primaryStore() { return (this.CaseFormIn.controls.generalInfoFormGroup as FormGroup).controls.primaryStore; }
</code>```

and in template

```<code> <div class="error-message" *ngIf="primaryStore.touched && primaryStore.errors">
      Primary Store is a Required Field.
 </div>
</code>```

Body:
In Component I Have

  @Input() CaseFormIn: FormGroup;
get f() { return this.CaseFormIn.controls; }

In Template

           Primary Store is a Required Field.

in development code is working fine but getting below error in prod mode
 Property 'controls' does not exist on type 'AbstractControl'.

Body:
try it

get primaryStore() { return (this.CaseFormIn.controls.generalInfoFormGroup as FormGroup).controls.primaryStore; }

and in template

 <div class="error-message" *ngIf="primaryStore.touched && primaryStore.errors">
      Primary Store is a Required Field.
 </div>


问:
Match nodes where all relations satisfy constraints
I'm looking to find nodes that have relations where all relations satisfy that constraint. the exact example is do you have a relation in a list.

the graph is bascially cocktails, with the relations being ingredients. given a list of ingredients i want to know what I can make.

```<code>with ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as list
...
should return Negroni, Boulevardier, ...
</code>```

I've been finding this tricky because we want to make sure that all relations of a node satisfy the constraint, but the number of nodes could very easily be a subset of the list and not an exact match to the ingredient list.

this is the best I've done so far, and it only works if you have all the ingredients, but nothing extra.

```<code>with ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as list
MATCH (n:Cocktail)-[h:HAS]-(x)
WITH list, count(list) AS lth, n, COLLECT(DISTINCT x.name) AS cx, collect(DISTINCT h) as hh
WHERE ALL (i IN list WHERE i IN cx)
RETURN n
</code>```

I'ved looked at stackoverflow.com/a/62053139/974731. I don't think it solves my problem

as you can see the addition of Bourbon removes the Negroni, which shouldn't happen since all we've done is add an ingredient to our bar.

答:
This should return all cocktails whose needed ingredients are in the have list.

```<code>WITH ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as have
MATCH (c:Cocktail)-[:HAS]->(x)
WITH have, c, COLLECT(x.name) AS needed
WHERE ALL(n IN needed WHERE n IN have)
RETURN c
</code>```

Or, if you pass have as a parameter:

```<code>MATCH (c:Cocktail)-[:HAS]->(x)
WITH c, COLLECT(x.name) AS needed
WHERE ALL(n IN needed WHERE n IN $have)
RETURN c
</code>```

Body:
I'm looking to find nodes that have relations where all relations satisfy that constraint. the exact example is do you have a relation in a list.

the graph is bascially cocktails, with the relations being ingredients. given a list of ingredients i want to know what I can make.

with ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as list
...
should return Negroni, Boulevardier, ...

I've been finding this tricky because we want to make sure that all relations of a node satisfy the constraint, but the number of nodes could very easily be a subset of the list and not an exact match to the ingredient list.

this is the best I've done so far, and it only works if you have all the ingredients, but nothing extra.

with ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as list
MATCH (n:Cocktail)-[h:HAS]-(x)
WITH list, count(list) AS lth, n, COLLECT(DISTINCT x.name) AS cx, collect(DISTINCT h) as hh
WHERE ALL (i IN list WHERE i IN cx)
RETURN n

I'ved looked at stackoverflow.com/a/62053139/974731. I don't think it solves my problem

as you can see the addition of Bourbon removes the Negroni, which shouldn't happen since all we've done is add an ingredient to our bar.

Body:
This should return all cocktails whose needed ingredients are in the have list.

WITH ['Sweet Vermouth', 'Gin', 'Campari', 'Bourbon'] as have
MATCH (c:Cocktail)-[:HAS]->(x)
WITH have, c, COLLECT(x.name) AS needed
WHERE ALL(n IN needed WHERE n IN have)
RETURN c

Or, if you pass have as a parameter:

MATCH (c:Cocktail)-[:HAS]->(x)
WITH c, COLLECT(x.name) AS needed
WHERE ALL(n IN needed WHERE n IN $have)
RETURN c


问:
How do I make my A star search algorithm more efficient?
I have a grid in matplotlib (20*20 or 40*40 based on user's choice) that contains data divided based on LatLong location. Each cell in that grid represents a 0.002 or 0.001 area (ex: [-70.55, 43.242] to [-70.548, 43.244]). The grid is coloured basesd on threshold value, say anything above 30 is green and anything below is red.

I implemented the A start algorithm to go from one location (cell) to another on that graph while avoiding all green cells. The cost of traveling on a border of a green and red cell is 1.3 while the diagonal cost is 1.5, and traveling between two red cells is 1.

I'm using the diagonal distance heuristic, and for each cell I'm getting all possible neighbours and setting their G value based on the threshold.

Now I'm able to get a correct path most of the time, and for cells that are nearby, it runs at sub 1 sec. but when I go further it takes 14-18 seconds.

I don't understand what wrong I'm doing here? I've been trying to figure out a way to improve it but failed.

Here's a fragment of the algorithm. I would like to note that determining the accessible neighbours and setting the G value might not be issue here because each function call runs at around 0.02 - 0.03 seconds.

Any advice is appreciated! Thanks

```<code>def a_star(self, start, end):
    startNode = Node(None, start)
    endNode = Node(None, end)
    openList = []
    closedList = []
    openList.append(startNode)

    while len(openList) > 0:

        current = openList[0]
        if current.location == endNode.location:
            path = []
            node = current
            while node is not None:
                path.append(node)
                node = node.parent
            return path[::-1]

        openList.pop(0)
        closedList.append(current)

       # This takes around 0.02 0.03 seconds
        neighbours = self.get_neighbors(current)

        for neighbour in neighbours:
            append = True
            for node in closedList:
                if neighbour.location == node.location:
                    append = False
                    break
            for openNode in openList:
                if neighbour.location == openNode.location:
                    if neighbour.g < openNode.g:
                        append = False
                        openNode.g = neighbour.g
                        break
            if append:

                neighbour.h = round(self.heuristic(neighbour.location, endNode.location), 3)
                neighbour.f = round(neighbour.g + neighbour.h, 3)

                bisect.insort_left(openList, neighbour)
    return False
</code>```

Edit: Add Node fragment

```<code> class Node:
    def __init__(self, parent, location):
        self.parent = parent
        self.location = location
        self.g = 0
        self.h = 0
        self.f = 0
</code>```

Edit 2: Add Image

Circle is start location, star is destination. Yellow cells are not accessible, so no diagonal path on yellow cells, and cannot travel between two yellow cells.

答:
As @lenic already pointed out, the inner loops you have do not belong in an A* algorithm.

The first one (for node in closedList) should be replaced by a check of whether a node is in a set (instead of a list): that way you don't need iteration.

The seconde one (openNode in openList) is unnecessary when you initialise all g property values with infinity (except the start node). Then you can just compare the new g value with the one that is already stored in the neighbor node.

Furthermore, I would suggest creating nodes for the whole graph as soon as the graph is created. That will be of benefit when you need to do multiple queries on the same graph.

Also, instead of bisect.insort_left I would propose using heapq.heappush. This will be faster, as it does not really sort the queue completely, but just ensures the heap property is maintained. The time complexity is the same though. More importantly, the time complexity of getting the next value from it is better than openList.pop(0).

I would suggest working with costs 10, 13 and 15 instead of 1, 1.3 and 1.5, as integer operations have no issues with precision.

For the same reason I would not work with fractional location coordinates. Since they are all just as far apart (e.g. 0.002), we can just use sequential integers (0, 1, 2, ...) for both coordinates. An extra function could take the solution and a reference coordinate pair to convert those integer coordinates back to "world" coordinates.

I have made some assumptions:

It is strictly forbidden to go through "hostile" cells. No edges will exist for crossing those. For instance, if the starting location is in the middle of four hostile cells, there will be no path. One could consider an alternative where these edges would get an extreme high cost, so that you would always be able to propose a path.

The straight edges on the boundary of the grid are all allowed. Their cost will be 1.3 (13) when the single cell, that neighbors it, is hostile. So actually in each of the two dimensions there is one more location than there are cells

The threshold input will be a fraction between 0 and 1, indicating the fraction of the cells that should be friendly with respect to the total number of cells, and this value will be converted to a "split" value to distinguish between friendly and hostile cells.

Here is the code you could use as inspiration:

```<code>from heapq import heappop, heappush

class Node:
    def __init__(self, location):
        self.location = location
        self.neighbors = []
        self.parent = None
        self.g = float('inf')
        self.f = 0

    def clear(self):
        self.parent = None
        self.g = float('inf')
        self.f = 0

    def addneighbor(self, cost, other):
        # add edge in both directions
        self.neighbors.append((cost, other))
        other.neighbors.append((cost, self))

    def __gt__(self, other):  # make nodes comparable
        return self.f > other.f

    def __repr__(self):
        return str(self.location)

class Graph:
    def __init__(self, grid, thresholdfactor):
        # get value that corresponds with thresholdfactor (which should be between 0 and 1)
        values = sorted([value for row in grid for value in row])
        splitvalue = values[int(len(values) * thresholdfactor)]
        print("split at ", splitvalue)
        # simplify grid values to booleans and add extra row/col of dummy cells all around
        width = len(grid[0]) + 1
        height = len(grid) + 1
        colors = ([[False] * (width + 1)] +
            [[False] + [value < splitvalue for value in row] + [False] for row in grid] +
            [[False] * (width + 1)])

        nodes = []
        for i in range(height):
            noderow = []
            nodes.append(noderow)
            for j in range(width):
                node = Node((i, j))
                noderow.append(node)
                cells = [colors[i+1][j]] + colors[i][j:j+2]  # 3 cells around location: SW, NW, NE
                for di, dj in ((1, 0), (0, 0), (0, 1), (0, 2)):  # 4 directions: W, NW, N, NE
                    cost = 0
                    if (di + dj) % 2:  # straight
                        # if both cells are hostile, then not allowed
                        if cells[0] or cells[1]:  # at least one friendly cell
                            # if one is hostile, higher cost
                            cost = 13 if cells[0] != cells[1] else 10
                        cells.pop(0)
                    elif cells[0]:  # diagonal: cell must be friendly
                        cost = 15
                    if cost:
                        node.addneighbor(cost, nodes[i-1+di][j-1+dj])
        self.nodes = nodes

    @staticmethod
    def reconstructpath(node):
        path = []
        while node is not None:
            path.append(node)
            node = node.parent
        path.reverse()
        return path

    @staticmethod
    def heuristic(a, b):
        # optimistic score, assuming all cells are friendly
        dy = abs(a[0] - b[0])
        dx = abs(a[1] - b[1])
        return min(dx, dy) * 15 + abs(dx - dy) * 10

    def clear(self):
        # remove search data from graph
        for row in self.nodes:
            for node in row:
                node.clear()

    def a_star(self, start, end):
        self.clear()
        startnode = self.nodes[start[0]][start[1]]
        endnode = self.nodes[end[0]][end[1]]
        startnode.g = 0
        openlist = [startnode]
        closed = set()
        while openlist:
            node = heappop(openlist)
            if node in closed:
                continue
            closed.add(node)
            if node == endnode:
                return self.reconstructpath(endnode)
            for weight, neighbor in node.neighbors:
                g = node.g + weight
                if g < neighbor.g:
                    neighbor.g = g
                    neighbor.f = g + self.heuristic(neighbor.location, endnode.location)
                    neighbor.parent = node
                    heappush(openlist, neighbor)
</code>```

I encoded the graph you included as image, to see how the code would behave:

```<code>grid = [
    [38, 32, 34, 24,  0, 82,  5, 41, 11, 32,  0, 16,  0,113, 49, 34, 24,  6, 15, 35],
    [61, 61,  8, 35, 65, 31, 53, 25, 66,  0, 21,  0,  9,  0, 31, 75, 20,  8,  3, 29],
    [43, 66, 47,114, 38, 41,  1,108,  9,  0,  0,  0, 39,  0, 27, 72, 19, 14, 24, 25],
    [45,  5, 37, 23,102, 25, 49, 34, 41, 49, 35, 15, 29, 21, 66, 67, 44, 31, 38, 91],
    [47, 94, 48, 69, 33, 95, 18, 75, 28, 70, 38, 78, 48, 88, 21, 66, 44, 70, 75, 23],
    [23, 84, 53, 23, 92, 14, 71, 12,139, 30, 63, 82, 16, 49, 76, 56,119,100, 47, 21],
    [30,  0, 32, 90,  0,195, 85, 65, 18, 57, 47, 61, 40, 32,109,255, 88, 98, 39,  0],
    [ 0,  0,  0,  0, 39, 39, 76,167, 73,140, 58, 56, 94, 61,212,222,141, 50, 41, 20],
    [ 0,  0,  0,  5,  0,  0, 21,  2,132,100,218, 81,  0, 62,135, 42,131, 80, 14, 19],
    [ 0,  0,  0,  0,  0, 15,  9, 55, 70, 71, 42,117, 65, 63, 59, 81,  4, 40, 77, 46],
    [ 0,  0,  0,  0, 55, 52,101, 93, 30,166, 56, 19, 76,103, 54, 37, 24, 23, 59, 98],
    [ 0,  0,  0,  0,  9,  9, 44,149, 11,134, 90, 64, 44, 57, 61, 79,270,201, 84,  6],
    [ 0,  0,  0, 22,  1, 15,  0, 25, 30,101,154, 60, 97, 64, 15,162, 27, 91, 71,  0],
    [ 0,  0,  1, 35,  5, 10,  0, 55, 25,  0,200, 81, 31, 53, 42, 74,127,154,  7,  0],
    [ 0,  0,187, 17, 45, 66, 91,191, 70,189, 18, 25, 67, 32, 40, 79,103, 79, 59,  0],
    [ 0, 21, 16, 14, 19, 58,278, 56,128, 95,  3, 52,  9, 27, 25, 43, 62, 25, 38,  0],
    [ 4,  3, 11, 26,119,165, 53, 85, 46, 81, 19, 11, 12, 19, 18,  9, 16,  6, 37,  0],
    [ 5,  0,  0, 65,158,153,118, 38,123, 46, 28, 24,  0, 21, 11, 20,  5,  1, 10,  0],
    [17,  4, 28, 81,101,101, 46, 25, 44, 12, 41,  6, 27,  8,  4, 32, 40,  1,  1,  0],
    [26, 20, 84, 42,112, 27, 14, 16,  5, 13,  3, 43,  6, 18, 12, 44,  5,  0,  0,  5]
]

graph = Graph(grid, 0.5) # provide the threshold at initialisation
path = graph.a_star((7, 4), (14, 18))
print(path)
</code>```

Body:
I have a grid in matplotlib (20*20 or 40*40 based on user's choice) that contains data divided based on LatLong location. Each cell in that grid represents a 0.002 or 0.001 area (ex: [-70.55, 43.242] to [-70.548, 43.244]). The grid is coloured basesd on threshold value, say anything above 30 is green and anything below is red.

I implemented the A start algorithm to go from one location (cell) to another on that graph while avoiding all green cells. The cost of traveling on a border of a green and red cell is 1.3 while the diagonal cost is 1.5, and traveling between two red cells is 1.

I'm using the diagonal distance heuristic, and for each cell I'm getting all possible neighbours and setting their G value based on the threshold.

Now I'm able to get a correct path most of the time, and for cells that are nearby, it runs at sub 1 sec. but when I go further it takes 14-18 seconds.

I don't understand what wrong I'm doing here? I've been trying to figure out a way to improve it but failed.

Here's a fragment of the algorithm. I would like to note that determining the accessible neighbours and setting the G value might not be issue here because each function call runs at around 0.02 - 0.03 seconds.

Any advice is appreciated! Thanks

def a_star(self, start, end):
    startNode = Node(None, start)
    endNode = Node(None, end)
    openList = []
    closedList = []
    openList.append(startNode)

    while len(openList) > 0:

        current = openList[0]
        if current.location == endNode.location:
            path = []
            node = current
            while node is not None:
                path.append(node)
                node = node.parent
            return path[::-1]

        openList.pop(0)
        closedList.append(current)

       # This takes around 0.02 0.03 seconds
        neighbours = self.get_neighbors(current)

        for neighbour in neighbours:
            append = True
            for node in closedList:
                if neighbour.location == node.location:
                    append = False
                    break
            for openNode in openList:
                if neighbour.location == openNode.location:
                    if neighbour.g < openNode.g:
                        append = False
                        openNode.g = neighbour.g
                        break
            if append:

                neighbour.h = round(self.heuristic(neighbour.location, endNode.location), 3)
                neighbour.f = round(neighbour.g + neighbour.h, 3)

                bisect.insort_left(openList, neighbour)
    return False

Edit: Add Node fragment

 class Node:
    def __init__(self, parent, location):
        self.parent = parent
        self.location = location
        self.g = 0
        self.h = 0
        self.f = 0

Edit 2: Add Image

Circle is start location, star is destination. Yellow cells are not accessible, so no diagonal path on yellow cells, and cannot travel between two yellow cells.

Body:
As @lenic already pointed out, the inner loops you have do not belong in an A* algorithm.

The first one (for node in closedList) should be replaced by a check of whether a node is in a set (instead of a list): that way you don't need iteration.

The seconde one (openNode in openList) is unnecessary when you initialise all g property values with infinity (except the start node). Then you can just compare the new g value with the one that is already stored in the neighbor node.

Furthermore, I would suggest creating nodes for the whole graph as soon as the graph is created. That will be of benefit when you need to do multiple queries on the same graph.

Also, instead of bisect.insort_left I would propose using heapq.heappush. This will be faster, as it does not really sort the queue completely, but just ensures the heap property is maintained. The time complexity is the same though. More importantly, the time complexity of getting the next value from it is better than openList.pop(0).

I would suggest working with costs 10, 13 and 15 instead of 1, 1.3 and 1.5, as integer operations have no issues with precision.

For the same reason I would not work with fractional location coordinates. Since they are all just as far apart (e.g. 0.002), we can just use sequential integers (0, 1, 2, ...) for both coordinates. An extra function could take the solution and a reference coordinate pair to convert those integer coordinates back to "world" coordinates.

I have made some assumptions:

It is strictly forbidden to go through "hostile" cells. No edges will exist for crossing those. For instance, if the starting location is in the middle of four hostile cells, there will be no path. One could consider an alternative where these edges would get an extreme high cost, so that you would always be able to propose a path.

The straight edges on the boundary of the grid are all allowed. Their cost will be 1.3 (13) when the single cell, that neighbors it, is hostile. So actually in each of the two dimensions there is one more location than there are cells

The threshold input will be a fraction between 0 and 1, indicating the fraction of the cells that should be friendly with respect to the total number of cells, and this value will be converted to a "split" value to distinguish between friendly and hostile cells.

Here is the code you could use as inspiration:

from heapq import heappop, heappush

class Node:
    def __init__(self, location):
        self.location = location
        self.neighbors = []
        self.parent = None
        self.g = float('inf')
        self.f = 0

    def clear(self):
        self.parent = None
        self.g = float('inf')
        self.f = 0

    def addneighbor(self, cost, other):
        # add edge in both directions
        self.neighbors.append((cost, other))
        other.neighbors.append((cost, self))

    def __gt__(self, other):  # make nodes comparable
        return self.f > other.f

    def __repr__(self):
        return str(self.location)

class Graph:
    def __init__(self, grid, thresholdfactor):
        # get value that corresponds with thresholdfactor (which should be between 0 and 1)
        values = sorted([value for row in grid for value in row])
        splitvalue = values[int(len(values) * thresholdfactor)]
        print("split at ", splitvalue)
        # simplify grid values to booleans and add extra row/col of dummy cells all around
        width = len(grid[0]) + 1
        height = len(grid) + 1
        colors = ([[False] * (width + 1)] +
            [[False] + [value < splitvalue for value in row] + [False] for row in grid] +
            [[False] * (width + 1)])

        nodes = []
        for i in range(height):
            noderow = []
            nodes.append(noderow)
            for j in range(width):
                node = Node((i, j))
                noderow.append(node)
                cells = [colors[i+1][j]] + colors[i][j:j+2]  # 3 cells around location: SW, NW, NE
                for di, dj in ((1, 0), (0, 0), (0, 1), (0, 2)):  # 4 directions: W, NW, N, NE
                    cost = 0
                    if (di + dj) % 2:  # straight
                        # if both cells are hostile, then not allowed
                        if cells[0] or cells[1]:  # at least one friendly cell
                            # if one is hostile, higher cost
                            cost = 13 if cells[0] != cells[1] else 10
                        cells.pop(0)
                    elif cells[0]:  # diagonal: cell must be friendly
                        cost = 15
                    if cost:
                        node.addneighbor(cost, nodes[i-1+di][j-1+dj])
        self.nodes = nodes

    @staticmethod
    def reconstructpath(node):
        path = []
        while node is not None:
            path.append(node)
            node = node.parent
        path.reverse()
        return path

    @staticmethod
    def heuristic(a, b):
        # optimistic score, assuming all cells are friendly
        dy = abs(a[0] - b[0])
        dx = abs(a[1] - b[1])
        return min(dx, dy) * 15 + abs(dx - dy) * 10

    def clear(self):
        # remove search data from graph
        for row in self.nodes:
            for node in row:
                node.clear()

    def a_star(self, start, end):
        self.clear()
        startnode = self.nodes[start[0]][start[1]]
        endnode = self.nodes[end[0]][end[1]]
        startnode.g = 0
        openlist = [startnode]
        closed = set()
        while openlist:
            node = heappop(openlist)
            if node in closed:
                continue
            closed.add(node)
            if node == endnode:
                return self.reconstructpath(endnode)
            for weight, neighbor in node.neighbors:
                g = node.g + weight
                if g < neighbor.g:
                    neighbor.g = g
                    neighbor.f = g + self.heuristic(neighbor.location, endnode.location)
                    neighbor.parent = node
                    heappush(openlist, neighbor)

I encoded the graph you included as image, to see how the code would behave:

grid = [
    [38, 32, 34, 24,  0, 82,  5, 41, 11, 32,  0, 16,  0,113, 49, 34, 24,  6, 15, 35],
    [61, 61,  8, 35, 65, 31, 53, 25, 66,  0, 21,  0,  9,  0, 31, 75, 20,  8,  3, 29],
    [43, 66, 47,114, 38, 41,  1,108,  9,  0,  0,  0, 39,  0, 27, 72, 19, 14, 24, 25],
    [45,  5, 37, 23,102, 25, 49, 34, 41, 49, 35, 15, 29, 21, 66, 67, 44, 31, 38, 91],
    [47, 94, 48, 69, 33, 95, 18, 75, 28, 70, 38, 78, 48, 88, 21, 66, 44, 70, 75, 23],
    [23, 84, 53, 23, 92, 14, 71, 12,139, 30, 63, 82, 16, 49, 76, 56,119,100, 47, 21],
    [30,  0, 32, 90,  0,195, 85, 65, 18, 57, 47, 61, 40, 32,109,255, 88, 98, 39,  0],
    [ 0,  0,  0,  0, 39, 39, 76,167, 73,140, 58, 56, 94, 61,212,222,141, 50, 41, 20],
    [ 0,  0,  0,  5,  0,  0, 21,  2,132,100,218, 81,  0, 62,135, 42,131, 80, 14, 19],
    [ 0,  0,  0,  0,  0, 15,  9, 55, 70, 71, 42,117, 65, 63, 59, 81,  4, 40, 77, 46],
    [ 0,  0,  0,  0, 55, 52,101, 93, 30,166, 56, 19, 76,103, 54, 37, 24, 23, 59, 98],
    [ 0,  0,  0,  0,  9,  9, 44,149, 11,134, 90, 64, 44, 57, 61, 79,270,201, 84,  6],
    [ 0,  0,  0, 22,  1, 15,  0, 25, 30,101,154, 60, 97, 64, 15,162, 27, 91, 71,  0],
    [ 0,  0,  1, 35,  5, 10,  0, 55, 25,  0,200, 81, 31, 53, 42, 74,127,154,  7,  0],
    [ 0,  0,187, 17, 45, 66, 91,191, 70,189, 18, 25, 67, 32, 40, 79,103, 79, 59,  0],
    [ 0, 21, 16, 14, 19, 58,278, 56,128, 95,  3, 52,  9, 27, 25, 43, 62, 25, 38,  0],
    [ 4,  3, 11, 26,119,165, 53, 85, 46, 81, 19, 11, 12, 19, 18,  9, 16,  6, 37,  0],
    [ 5,  0,  0, 65,158,153,118, 38,123, 46, 28, 24,  0, 21, 11, 20,  5,  1, 10,  0],
    [17,  4, 28, 81,101,101, 46, 25, 44, 12, 41,  6, 27,  8,  4, 32, 40,  1,  1,  0],
    [26, 20, 84, 42,112, 27, 14, 16,  5, 13,  3, 43,  6, 18, 12, 44,  5,  0,  0,  5]
]

graph = Graph(grid, 0.5) # provide the threshold at initialisation
path = graph.a_star((7, 4), (14, 18))
print(path)


问:
Error during model fit in machine learning
When I am trying to fit my model on X_train and y_train, it gives me an error as shown in the image. The term Alberta is one of the entry in the province column of the dataset. Here i am using Decision Tree and Random forest as it is an unbalanced dataset. Please help me to resolve this error. I don't know where am i going wrong..

答:
This probably happens because you have both numerical values and strings in the dataset.
Some solutions I would suggest are:

Go through the dataset and drop unnecessary features/columns (be careful that you won't drop important features).

Convert the categorical type columns into numeric to get rid of strings.


问:
How to remove the default Navigation Bar space in SwiftUI NavigationView
I am new to SwiftUI (like most people) and trying to figure out how to remove some whitespace above a List that I embedded in a NavigationView.

In this image, you can see that there is some white space above the List.

What I want to accomplish is this:

I've tried using:

```<code>.navigationBarHidden(true)
</code>```

but this did not make any noticeable changes.

I'm currently setting up my navigiationView like this:

```<code>NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
        .navigationBarHidden(true)
}
</code>```

where FileBrowserView is a view with a List and FileCells defined like this:

```<code>List {
   Section(header: Text("Root")) {
       FileCell(name: "Test", fileType: "JPG",fileDesc: "Test number 1")
       FileCell(name: "Test 2", fileType: "txt",fileDesc: "Test number 2")
       FileCell(name: "test3", fileType: "fasta", fileDesc: "")
    }
}
</code>```

I do want to note that the ultimate goal here is that you will be able to click on these cells to navigate deeper into a file tree and thus should display a Back button on the bar on deeper navigation, but I do not want anything at the top as such during my initial view.

答:
I also tried all the solutions mentioned on this page and only found @graycampbell solution the one to be working well, with well-working animations. So I tried to create a value I can just use throughout the app that I can access anywhere by the example of hackingwithswift.com

I created an ObservableObject class

```<code>class NavBarPreferences: ObservableObject {
    @Published var navBarIsHidden = true
}
</code>```

And pass it on to the initial view in the SceneDelegate like so

```<code>var navBarPreferences = NavBarPreferences()
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))
</code>```

Then in the ContentView we can keep track of this Observable object like so and create a link to SomeView:

```<code>struct ContentView: View {
    //This variable listens to the ObservableObject class
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        NavigationView {
                NavigationLink (
                destination: SomeView()) {
                    VStack{
                        Text("Hello first screen")
                            .multilineTextAlignment(.center)
                            .accentColor(.black)
                    }
                }
                .navigationBarTitle(Text(""),displayMode: .inline)
                .navigationBarHidden(navBarPrefs.navBarIsHidden)
                .onAppear{
                    self.navBarPrefs.navBarIsHidden = true
            }
        }
    }
}
</code>```

And then when accessing the second view (SomeView), we hide it again like this:

```<code>struct SomeView: View {
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        Text("Hello second screen")
        .onAppear {
            self.navBarPrefs.navBarIsHidden = false
        }
    }
}
</code>```

To keep previews working add the NavBarPreferences to the preview like so:

```<code>struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        SomeView().environmentObject(NavBarPreferences())
    }
}
</code>```

Body:
I am new to SwiftUI (like most people) and trying to figure out how to remove some whitespace above a List that I embedded in a NavigationView.

In this image, you can see that there is some white space above the List.

What I want to accomplish is this:

I've tried using:

.navigationBarHidden(true)

but this did not make any noticeable changes.

I'm currently setting up my navigiationView like this:

NavigationView {
    FileBrowserView(jsonFromCall: URLRetrieve(URLtoFetch: applicationDelegate.apiURL))
        .navigationBarHidden(true)
}

where FileBrowserView is a view with a List and FileCells defined like this:

List {
   Section(header: Text("Root")) {
       FileCell(name: "Test", fileType: "JPG",fileDesc: "Test number 1")
       FileCell(name: "Test 2", fileType: "txt",fileDesc: "Test number 2")
       FileCell(name: "test3", fileType: "fasta", fileDesc: "")
    }
}

I do want to note that the ultimate goal here is that you will be able to click on these cells to navigate deeper into a file tree and thus should display a Back button on the bar on deeper navigation, but I do not want anything at the top as such during my initial view.

Body:
I also tried all the solutions mentioned on this page and only found @graycampbell solution the one to be working well, with well-working animations. So I tried to create a value I can just use throughout the app that I can access anywhere by the example of hackingwithswift.com

I created an ObservableObject class

class NavBarPreferences: ObservableObject {
    @Published var navBarIsHidden = true
}

And pass it on to the initial view in the SceneDelegate like so

var navBarPreferences = NavBarPreferences()
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(navBarPreferences))

Then in the ContentView we can keep track of this Observable object like so and create a link to SomeView:

struct ContentView: View {
    //This variable listens to the ObservableObject class
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        NavigationView {
                NavigationLink (
                destination: SomeView()) {
                    VStack{
                        Text("Hello first screen")
                            .multilineTextAlignment(.center)
                            .accentColor(.black)
                    }
                }
                .navigationBarTitle(Text(""),displayMode: .inline)
                .navigationBarHidden(navBarPrefs.navBarIsHidden)
                .onAppear{
                    self.navBarPrefs.navBarIsHidden = true
            }
        }
    }
}

And then when accessing the second view (SomeView), we hide it again like this:

struct SomeView: View {
    @EnvironmentObject var navBarPrefs: NavBarPreferences

    var body: some View {
        Text("Hello second screen")
        .onAppear {
            self.navBarPrefs.navBarIsHidden = false
        }
    }
}

To keep previews working add the NavBarPreferences to the preview like so:

struct SomeView_Previews: PreviewProvider {
    static var previews: some View {
        SomeView().environmentObject(NavBarPreferences())
    }
}


问:
Why is this happening on my code although I did not return any value from a method?
I wrote some Java code;

```<code>int quantity = 0;

public void submitOrder(View view) {
    displayMessage(createOrderSummary());
}

public void increment(View view) {
    quantity = quantity + 1;
    display(quantity);
}

public void decrement(View view) {
    quantity = quantity - 1;
    display(quantity);
}

private String createOrderSummary() {
    String message = "Quantity : " + quantity;
    return message;
}
</code>```

This code is working fine. When I press + and - buttons on app, it is executing increment and decrement methods. But in those methods, I used void. Which I learned that means "no return" on that method.

So, how can this code works as showing the quantity variable changed; although it was changed in a method which has no return statement?

I think it should show quantity as 0, because the changed quantity values were not returning from those methods. Where am I wrong?

答:
Actually not returning the integer doesn't mean that it's not applying the change (e.g: incrementing  quantity = quantity + 1; )

void means that no value will be returned to use in the place where the function is called (for an e.g in a different class). But if you call it, it will still execute the code inside it.

Body:
I wrote some Java code;

int quantity = 0;

public void submitOrder(View view) {
    displayMessage(createOrderSummary());
}

public void increment(View view) {
    quantity = quantity + 1;
    display(quantity);
}

public void decrement(View view) {
    quantity = quantity - 1;
    display(quantity);
}

private String createOrderSummary() {
    String message = "Quantity : " + quantity;
    return message;
}

This code is working fine. When I press + and - buttons on app, it is executing increment and decrement methods. But in those methods, I used void. Which I learned that means "no return" on that method.

So, how can this code works as showing the quantity variable changed; although it was changed in a method which has no return statement?

I think it should show quantity as 0, because the changed quantity values were not returning from those methods. Where am I wrong?


问:
How to count previous siblings in TestCafe?
Summary:

I'm using TestCafe and I know it's not a difficult question which I'm asking (JQuery has a solution for this). I'm looking for a solution in TestCafe.

Question:

I need to know how many (count in integer) previous siblings (button) exists from the highlighted blue. In my case the answer should be 4.

What I've done so far

As per the screenshot, I'm in the element index 4 (but I don't know). I've used following selector to reach the element:

Selector('div.group-name').withExactText('f61ck72g83m')

Now, to count the previous sibling I tried this:

Selector('div.group-name').withExactText('f61ck72g83m').parent('button.group-info').prevSibling('button').count

and this returns a promise which I don't want:
ReExecutablePromise { _then: [], _fn: [Function], _taskPromise: null }

答: I missed await before calling the element. Silly question indeed.


问:
Flutter command not found
Apparently, none of the Flutter commands are working in the terminal of Android Studio which I believe I am trying to run it at the root of my project.

Output:

```<code>bash: flutter: command not found
</code>```

答: For those using a Z shell resource (.zshrc), navigate to your home directory and open .zprofile, copy and paste this: export PATH=[PATH_TO_FLUTTER_DIRECTORY]/flutter/bin:$PATH

Title: Flutter command not found

Body:
Apparently, none of the Flutter commands are working in the terminal of Android Studio which I believe I am trying to run it at the root of my project.

Output:

bash: flutter: command not found


问:
Postgresql - query problem
I have a variable which is in this format 2011-05-13.
I want to make a query that adds one day to this variable and searches for days like this in the database.

I made this query but it doesnt work.

```<code>select phone from employee where date like (select date '2011-05-13' + 1) %
</code>```

Can anyone help?

答:
Try the following:</p>

```<code>SELECT phone FROM employee WHERE to_char(date, 'yyyy-mm-dd')::timestamp = ('2011-05-13'::timestamp + '1 day'::interval)
</code>```

Title: Postgresql - query problem

Body:
I have a variable which is in this format 2011-05-13.
I want to make a query that adds one day to this variable and searches for days like this in the database.

I made this query but it doesnt work.

select phone from employee where date like (select date '2011-05-13' + 1) %

Can anyone help?

Body:
Try the following:

SELECT phone FROM employee WHERE to_char(date, 'yyyy-mm-dd')::timestamp = ('2011-05-13'::timestamp + '1 day'::interval)


问:
Python: How to Create chucks of data contain X byte for each time
I am trying to write a simple function that take a data in hex format. However, the idea is I want to use for loop with round() so that each time the loop will print only 2KB (2048) of data (only 2048 byte for each time),

This is what I did, but did not work.

```<code>data = "4d5a90000300000004000000fff........"

def function_x(x):
    for i in range(0,int(round(len(data)/2048))):
        data_chunk = data[i*2047:(i+1)*2047]
        ....
        ....
        ....
        ....
</code>```

UPDATE: To make my question clear for you, I will provide some details. I am using Postgresql, Large objects specifically, However, to update this object or insert any new data on it, you must keep this note in you mind, which is mentioned in their documentation

The amount of data per page is defined to be LOBLKSIZE (which is currently BLCKSZ/4, or typically 2 kB "2048").

so I wrote this simple code to fit with their requirements, just do not know what is the the right numbers must be written instead of (?) marks that i put

for i in range(0,int(round(len(data)/??))):  > to divide the code into x number of pages, each page must contain 2048 byte only > data[i*??:(i+1)*??]

NOTE: if i == 0 because the first page must be updated not inserted according to their docs

here is the full code

```<code>data = "4d5a90000300000004000000fff........"
loid = 14697

def function_x(x):
        for i in range(0,int(round(len(data)/??))):
    data_chunk = data[i*??:(i+1)*??]
    if i == 0:
        sql = "UPDATE PG_LARGEOBJECT SET data=decode('%s', 'hex') where loid=%d and pageno=%d" % (data_chunk, loid, i)
    else:
        sql = "INSERT PG_LARGEOBJECT SET data=decode('%s', 'hex') where loid=%d and pageno=%d" % (data_chunk, loid, i)
        ....
        ....
        ....
        ....
</code>```

Body:
I am trying to write a simple function that take a data in hex format. However, the idea is I want to use for loop with round() so that each time the loop will print only 2KB (2048) of data (only 2048 byte for each time),

This is what I did, but did not work.

data = "4d5a90000300000004000000fff........"

def function_x(x):
    for i in range(0,int(round(len(data)/2048))):
        data_chunk = data[i*2047:(i+1)*2047]
        ....
        ....
        ....
        ....

UPDATE: To make my question clear for you, I will provide some details. I am using Postgresql, Large objects specifically, However, to update this object or insert any new data on it, you must keep this note in you mind, which is mentioned in their documentation

The amount of data per page is defined to be LOBLKSIZE (which is currently BLCKSZ/4, or typically 2 kB "2048").

so I wrote this simple code to fit with their requirements, just do not know what is the the right numbers must be written instead of (?) marks that i put

for i in range(0,int(round(len(data)/??))):  > to divide the code into x number of pages, each page must contain 2048 byte only > data[i*??:(i+1)*??]

NOTE: if i == 0 because the first page must be updated not inserted according to their docs

here is the full code

data = "4d5a90000300000004000000fff........"
loid = 14697

def function_x(x):
        for i in range(0,int(round(len(data)/??))):
    data_chunk = data[i*??:(i+1)*??]
    if i == 0:
        sql = "UPDATE PG_LARGEOBJECT SET data=decode('%s', 'hex') where loid=%d and pageno=%d" % (data_chunk, loid, i)
    else:
        sql = "INSERT PG_LARGEOBJECT SET data=decode('%s', 'hex') where loid=%d and pageno=%d" % (data_chunk, loid, i)
        ....
        ....
        ....
        ....

Body:
You can use islice from itertools module:

from itertools import islice

a = '4d5a90000300000004000000fff'
length = 5

data = iter(a)
while True:
    elm = list(islice(data, length))
    if not elm:
        break
    print(elm)

Output:

['4', 'd', '5', 'a', '9']
['0', '0', '0', '0', '3']
['0', '0', '0', '0', '0']
['0', '0', '4', '0', '0']
['0', '0', '0', '0', 'f']
['f', 'f']


问:
'TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined'
I'm working on a project in React and ran into a problem that has me stumped.

Whenever I run yarn start I get this error:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type
string. Received type undefined

I have no idea why this is happening.

答:
In my case, it was because I (at one point) had reactn installed, which also includes its own version of React (for some reason).

After that had been installed (even after uninstalling again), this error occured.

I simply removed node_modules and ran npm install again, and it worked.


问:
Disable Console text-wrapping from within a program
I have used pyinstaller to compile my program into a standalone .exe.
The print functions my program uses requires there not to be any text wrapping when window size is too small (as this can cause some text to linger). I know there is a way to disable text wrapping from the properties menu in command prompt, but I was wondering if I could change this setting automatically from within the program.</p>

答:
I believe I found your answer here:

https://askubuntu.com/questions/73443/how-to-stop-the-terminal-from-wrapping-lines

Your script needs to run the command "tput rmam" to disable text wrapping. Then your script needs to be piped through "less -S". This probably needs to be wrapped in a sub-process that is embedded in your current process. Now your terminal will no longer wrap lines, you can still use the arrow keys to view more of lines that are too long.

Here is a mockup I wrote:

temp:

```<code>short line
long line long line long line long line long line long line long line long line long line long line long line long line long line
short line
</code>```

temp.py:

```<code>#!/usr/bin/env python

import pexpect as pe

b = pe.spawn('bash')
b.sendline('tput rmam')
b.sendline('less temp -S')
b.interact() # Imbed in your current process.
</code>```

Body:
I believe I found your answer here:

https://askubuntu.com/questions/73443/how-to-stop-the-terminal-from-wrapping-lines

Your script needs to run the command "tput rmam" to disable text wrapping. Then your script needs to be piped through "less -S". This probably needs to be wrapped in a sub-process that is embedded in your current process. Now your terminal will no longer wrap lines, you can still use the arrow keys to view more of lines that are too long.

Here is a mockup I wrote:

temp:

short line
long line long line long line long line long line long line long line long line long line long line long line long line long line
short line

temp.py:

#!/usr/bin/env python

import pexpect as pe

b = pe.spawn('bash')
b.sendline('tput rmam')
b.sendline('less temp -S')
b.interact() # Imbed in your current process.


问:
Reading a binary file in C: ftell returns results that sometimes are off by one
I'm trying to read a binary file that is in the following format:

number of images [4-byte int]

width [4-byte int]

    height [4-byte int]

    grayscale data [width * height bytes]

    (more elements of the same type)

That's the first function being called:

```<code>int process_file(const char *filename) {
    FILE *input_file = fopen(filename, "r");

    //Get number of images
    unsigned int number_of_images = read_int_from_file(input_file);

    //Allocate memory for all images
    struct image *images = malloc(sizeof(struct image) * number_of_images);

    read_images(images, number_of_images, input_file)
}
</code>```

Here's the image structure for anyone wondering:

```<code>struct image {
    unsigned int width;
    unsigned int height;
    unsigned char *data;
};
</code>```

And that's what read_int_from_file does:

```<code>static unsigned int read_int_from_file(FILE *file) {
    unsigned char chars[4];
    if (fread(&chars, sizeof(char), 4, file) != 4) {
        fprintf(stderr, "Couldn't read enough bytes!\n");
        return 0;
    }
    //Calculations follow that return right numbers
    return out;
}
</code>```

That's the rest:

```<code>static int read_images(struct image *images, unsigned int number_of_images, FILE * file) {
    struct image *current_image = images;

    int i;
    for (i = 0; i < number_of_images; i++) {
        read_image(current_image++, file)
    }

    return EXIT_SUCCESS;
}

static int read_image(struct image *image, FILE *file) {
    static long int expected_position = 4;

    if (ftell(file) != expected_position) {
        fprintf(stderr, "Reading @ %lu when should be @ %lu!",
                ftell(file), expected_position);
        exit(EXIT_FAILURE);
    }

    unsigned int width = read_int_from_file(file);
    unsigned int height = read_int_from_file(file);

    unsigned int size = width * height;

    unsigned char *data = malloc(sizeof(char) * size);
    if (data) {
        if (fread(data, sizeof(char), size, file) != size) {
            exit(EXIT_FAILURE);
        }

        image->width = width;
        image->height = height;
        image->data = data;

        expected_position += 2 * 4 + width * height;
        return EXIT_SUCCESS;
    } else {
        exit(EXIT_FAILURE);
    }
}
</code>```

The problem is that the file pointer is sometimes going ahead when it shouldn't do so, i.e. I'm hitting ftell(file) != expected_position. I'm getting it after a good amount of successful reads, but some good time before the end, too.

Does anyone have any idea why that may be? I mean, even if the numbers were wrong, that shouldn't happen, should it? Thanks!

答:
MS-DOS end-of-line sequences are Carriage Return, New Line (CR NL, 0x0D, 0x0A), and Unix uses simply New Line (NL or 0x0A).

Change the line

```<code>FILE *input_file = fopen(filename, "r");
</code>```

to

```<code>FILE *input_file = fopen(filename, "rb");
</code>```

Otherwise, the fread() function used to translate CR NL as NL, on Unix systems prior to POSIX standard "IEEE Std 1003.1-1988".

On MS-DOS, Windows and derivatives, it translates NL as CR NL.

These translations cause your opinion of the file position to differ from ftell()'s calculations.

Body:
I'm trying to read a binary file that is in the following format:

number of images [4-byte int]

width [4-byte int]

    height [4-byte int]

    grayscale data [width * height bytes]

    (more elements of the same type)

That's the first function being called:

int process_file(const char *filename) {
    FILE *input_file = fopen(filename, "r");

    //Get number of images
    unsigned int number_of_images = read_int_from_file(input_file);

    //Allocate memory for all images
    struct image *images = malloc(sizeof(struct image) * number_of_images);

    read_images(images, number_of_images, input_file)
}

Here's the image structure for anyone wondering:

struct image {
    unsigned int width;
    unsigned int height;
    unsigned char *data;
};

And that's what read_int_from_file does:

static unsigned int read_int_from_file(FILE *file) {
    unsigned char chars[4];
    if (fread(&chars, sizeof(char), 4, file) != 4) {
        fprintf(stderr, "Couldn't read enough bytes!\n");
        return 0;
    }
    //Calculations follow that return right numbers
    return out;
}

That's the rest:

static int read_images(struct image *images, unsigned int number_of_images, FILE * file) {
    struct image *current_image = images;

    int i;
    for (i = 0; i < number_of_images; i++) {
        read_image(current_image++, file)
    }

    return EXIT_SUCCESS;
}

static int read_image(struct image *image, FILE *file) {
    static long int expected_position = 4;

    if (ftell(file) != expected_position) {
        fprintf(stderr, "Reading @ %lu when should be @ %lu!",
                ftell(file), expected_position);
        exit(EXIT_FAILURE);
    }

    unsigned int width = read_int_from_file(file);
    unsigned int height = read_int_from_file(file);

    unsigned int size = width * height;

    unsigned char *data = malloc(sizeof(char) * size);
    if (data) {
        if (fread(data, sizeof(char), size, file) != size) {
            exit(EXIT_FAILURE);
        }

        image->width = width;
        image->height = height;
        image->data = data;

        expected_position += 2 * 4 + width * height;
        return EXIT_SUCCESS;
    } else {
        exit(EXIT_FAILURE);
    }
}

The problem is that the file pointer is sometimes going ahead when it shouldn't do so, i.e. I'm hitting ftell(file) != expected_position. I'm getting it after a good amount of successful reads, but some good time before the end, too.

Does anyone have any idea why that may be? I mean, even if the numbers were wrong, that shouldn't happen, should it? Thanks!

Body:
MS-DOS end-of-line sequences are Carriage Return, New Line (CR NL, 0x0D, 0x0A), and Unix uses simply New Line (NL or 0x0A).

Change the line

FILE *input_file = fopen(filename, "r");

to

FILE *input_file = fopen(filename, "rb");

Otherwise, the fread() function used to translate CR NL as NL, on Unix systems prior to POSIX standard "IEEE Std 1003.1-1988".

On MS-DOS, Windows and derivatives, it translates NL as CR NL.

These translations cause your opinion of the file position to differ from ftell()'s calculations.