问:
Swift UI - Using UIVIewControllerRepresentable to update logs
The logic I'm trying to create for my logging in the app is:

A ScrollView with a frame to control the height and allow the user to see logs from actions in the app, the logs should be scrollable to scroll up on previous appended logs.

I've created a log view model which allows the log to be set and then appends to a log array and then get.

The logs are set through actions in callbacks from various view controllers and actions from the user.

currently I have the logs being retrieved in the UIViewControllerRepresentable - updateUIViewController method.

The code works for each callback and for the user actions, the problems are: 5a. It's not scrollable to go to the top of the log messages, 5b. The log messages keep showing on the screen as updateUIViewController is continuously being called.

I was trying to think of a way to empty the array after each action, but not sure the best way to go about this.

Code:

LogViewModel:

```<code>import UIKit
import SwiftUI

class LogViewModel: ObservableObject{

    @Published var mTime: String = ""
    @Published var id: String = "#"
    @Published var mMessage: String = ""
    private var fullLogMessages: [String] = [""]

    func setTimeFormatter() -> DateFormatter {
        let formatter = DateFormatter()
           formatter.dateFormat = "HH:mm:ss"
           return formatter
    }

    func setTheTime(date: Date){
        self.mTime = setTimeFormatter().string(from: date)
    }

    func getTheTime() -> String{
        return self.mTime
    }

    func setTheMessage(mMessage: String) {
        ThreadUtil.runAsyncOnMainThread { [weak self] in
            self?.mMessage = mMessage
        }
    }

    func getTheMessage() -> String {
        return self.mMessage
    }

    func getTheFullLogMessage() -> [String] {
        let fullLog: String = getTheTime() + " - " + getTheGivenId() + " - " + getTheMessage()
        self.fullLogMessages.append(fullLog)
        return self.fullLogMessages
    }

    func setTheGivenId(id: String) {
        ThreadUtil.runAsyncOnMainThread { [weak self] in
            self?.id = id
        }
    }

    func getTheGivenId() -> String {
        return self.id
    }
}
</code>```

Controllers:
In each controller I've created a method like this to set the log messages:

```<code> func setTheLogMessages(message: String) {
        self.logViewModel.setTheTime(date: date)
        self.logViewModel.setTheMessage(mMessage: message)
    }
</code>```

In the view I have the UIViewControllerRepresentable:

```<code>struct MyScreenView_UI: UIViewControllerRepresentable{
    @ObservedObject var viewModel: myScreenViewModel
    @ObservedObject var logViewModel: LogViewModel
    @Binding var fullLogMessage: [String]

    func makeUIViewController(context: Context) -> some myViewController {
        print(#function)
        return myViewController(viewModel: viewModel, logViewModel: logViewModel)
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        print(#function)
        DispatchQueue.main.asyncAfter(deadline: .now() +  0.5) {
            fullLogMessage = logViewModel.getTheFullLogMessage()
        }
    }
}
</code>```

and the ScrollView for the UI:

```<code>    ScrollView{
        VStack(alignment: .leading, content: {
        Text("Logs")
            .font(.footnote).fontWeight(.medium)
        ForEach($fullLogMessage, id: \.self) { $logMessage in
            Text(logMessage)
                .font(.custom("FONT_NAME", size: 12))
                .disabled(true)
            }
          })
            .frame(width: 400, height: 50,  alignment: .leading)
    }
</code>```

答:
You haven't provided a  Minimal Reproducible Example but here is a simplified version of what seems to be what you are trying to do.

First, add a LogManager that can be created by ANY class or struct

```<code>struct LogManager{
    var name: String
    ///Simplified post that takes in the String and uses the name as the source
    func postMessage(message: String){
        postMessage(message: .init(timestamp: Date(), message: message, source: name))
    }
    //MARK: Notification
    ///Sends a Notification with the provided message
    func postMessage(message: Message){
        NotificationCenter.default.post(name: .logManagerMessage, object: message)
    }
    ///Adds an observer to the manager's notification
    func observeMessageNotification(observer: Any, selector: Selector){
        NotificationCenter.default.addObserver(observer, selector: selector, name: .logManagerMessage, object: nil)
    }
}
</code>```

Put at class or struct level the declaration for the manager

```<code>private let log = LogManager(name: "YourClassStructName")
</code>```

Then call

```<code>log.postMessage(message: "your message here")
</code>```

When you want to log a message.

In the ViewModel you would

subscribe to the notifications

maintain the array

Like below

```<code>class AppLogSampleViewModel: ObservableObject{
    static let shared: AppLogSampleViewModel = .init()
    private let manager = LogManager(name: "AppLogSampleViewModel")
    @Published var messages: [Message] = []
    private init(){
        //Observe the manager's notification
        manager.observeMessageNotification(observer: self, selector: #selector(postMessage(notification:)))
    }
    ///Puts the messages received into the array
    @objc
    func postMessage(notification: Notification){
        if notification.object is Message{
            messages.append(notification.object as! Message)
        }else{
            messages.append(.init(timestamp: Date(), message: "Notification received did not have message", source: "AppLogSampleViewModel :: \(#function)"))
        }
    }
}
</code>```

If your View won't be at the highest level you need to call.

```<code>let startListening: AppLogSampleViewModel = .shared
</code>```

In the ContentView or AppDelegate so the ViewModel starts listening as quickly as possible. You won't necessarily use it for anything but it needs to be called as soon as you want it to start logging messages.

Only the View that shows the messages uses the instance of the ViewModel.

```<code>struct AppLogSampleView: View {
    @StateObject var vm: AppLogSampleViewModel = .shared
    //Create this variable anywhere in your app
    private let log = LogManager(name: "AppLogSampleView")
    var body: some View {
        List{
            Button("post", action: {
                //Post like this anywhere in your app
                log.postMessage(message: "random from button")
            })
            DisclosureGroup("log messages"){
                ForEach(vm.messages, content: { message in
                    VStack{
                        Text(message.timestamp.description)
                        Text(message.message)
                        Text(message.source)
                    }
                })
            }
        }
    }
}
</code>```

Here is the rest of the code you need to get this sample working.

```<code>struct AppLogSampleView_Previews: PreviewProvider {
    static var previews: some View {
        AppLogSampleView()
    }
}
extension Notification.Name {
    static let logManagerMessage = Notification.Name("logManagerMessage")
}
struct Message: Identifiable{
    let id: UUID = .init()
    var timestamp: Date
    var message: String
    var source: String
}
</code>```

Only the one View that shows the messages needs access to the ViewModel and only one ViewModel subscribes to the notifications.

All the other classes and structs will just create an instance of the manager and call the method to post the messages.

There is no sharing/passing between the classes and structs everybody gets their own instance.

Your manager can have as many or as little methods as you want, mine usually mimics the Logger from osLog with log, info, debug and  error methods.

The specific methods call the osLog and 3rd party Analytics Services corresponding methods.

Also, the error method sends a notification that a ViewModel at the top level receives and shows an Alert.

To get all this detail working it takes a lot more code but you have the pattern with the code above.

In your code, in the updateUIViewController you break the single source if truth rule by copying the messages and putting them in another source of truth, right here.

```<code>fullLogMessage = logViewModel.getTheFullLogMessage()
</code>```

This is also done without a check to make sure that you don't go into an infinite loop. Anytime there is code in an update method you should check that the work actually needs to be done. Such as comparing that the new location doesn't already match the old location.

Body:
The logic I'm trying to create for my logging in the app is:

A ScrollView with a frame to control the height and allow the user to see logs from actions in the app, the logs should be scrollable to scroll up on previous appended logs.

I've created a log view model which allows the log to be set and then appends to a log array and then get.

The logs are set through actions in callbacks from various view controllers and actions from the user.

currently I have the logs being retrieved in the UIViewControllerRepresentable - updateUIViewController method.

The code works for each callback and for the user actions, the problems are: 5a. It's not scrollable to go to the top of the log messages, 5b. The log messages keep showing on the screen as updateUIViewController is continuously being called.

I was trying to think of a way to empty the array after each action, but not sure the best way to go about this.

Code:

LogViewModel:

import UIKit
import SwiftUI

class LogViewModel: ObservableObject{

    @Published var mTime: String = ""
    @Published var id: String = "#"
    @Published var mMessage: String = ""
    private var fullLogMessages: [String] = [""]

    func setTimeFormatter() -> DateFormatter {
        let formatter = DateFormatter()
           formatter.dateFormat = "HH:mm:ss"
           return formatter
    }

    func setTheTime(date: Date){
        self.mTime = setTimeFormatter().string(from: date)
    }

    func getTheTime() -> String{
        return self.mTime
    }

    func setTheMessage(mMessage: String) {
        ThreadUtil.runAsyncOnMainThread { [weak self] in
            self?.mMessage = mMessage
        }
    }

    func getTheMessage() -> String {
        return self.mMessage
    }

    func getTheFullLogMessage() -> [String] {
        let fullLog: String = getTheTime() + " - " + getTheGivenId() + " - " + getTheMessage()
        self.fullLogMessages.append(fullLog)
        return self.fullLogMessages
    }

    func setTheGivenId(id: String) {
        ThreadUtil.runAsyncOnMainThread { [weak self] in
            self?.id = id
        }
    }

    func getTheGivenId() -> String {
        return self.id
    }
}

Controllers:
In each controller I've created a method like this to set the log messages:

 func setTheLogMessages(message: String) {
        self.logViewModel.setTheTime(date: date)
        self.logViewModel.setTheMessage(mMessage: message)
    }

In the view I have the UIViewControllerRepresentable:

struct MyScreenView_UI: UIViewControllerRepresentable{
    @ObservedObject var viewModel: myScreenViewModel
    @ObservedObject var logViewModel: LogViewModel
    @Binding var fullLogMessage: [String]

    func makeUIViewController(context: Context) -> some myViewController {
        print(#function)
        return myViewController(viewModel: viewModel, logViewModel: logViewModel)
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        print(#function)
        DispatchQueue.main.asyncAfter(deadline: .now() +  0.5) {
            fullLogMessage = logViewModel.getTheFullLogMessage()
        }
    }
}

and the ScrollView for the UI:

    ScrollView{
        VStack(alignment: .leading, content: {
        Text("Logs")
            .font(.footnote).fontWeight(.medium)
        ForEach($fullLogMessage, id: \.self) { $logMessage in
            Text(logMessage)
                .font(.custom("FONT_NAME", size: 12))
                .disabled(true)
            }
          })
            .frame(width: 400, height: 50,  alignment: .leading)
    }

Body:
You haven't provided a  Minimal Reproducible Example but here is a simplified version of what seems to be what you are trying to do.

First, add a LogManager that can be created by ANY class or struct

struct LogManager{
    var name: String
    ///Simplified post that takes in the String and uses the name as the source
    func postMessage(message: String){
        postMessage(message: .init(timestamp: Date(), message: message, source: name))
    }
    //MARK: Notification
    ///Sends a Notification with the provided message
    func postMessage(message: Message){
        NotificationCenter.default.post(name: .logManagerMessage, object: message)
    }
    ///Adds an observer to the manager's notification
    func observeMessageNotification(observer: Any, selector: Selector){
        NotificationCenter.default.addObserver(observer, selector: selector, name: .logManagerMessage, object: nil)
    }
}

Put at class or struct level the declaration for the manager

private let log = LogManager(name: "YourClassStructName")

Then call

log.postMessage(message: "your message here")

When you want to log a message.

In the ViewModel you would

subscribe to the notifications

maintain the array

Like below

class AppLogSampleViewModel: ObservableObject{
    static let shared: AppLogSampleViewModel = .init()
    private let manager = LogManager(name: "AppLogSampleViewModel")
    @Published var messages: [Message] = []
    private init(){
        //Observe the manager's notification
        manager.observeMessageNotification(observer: self, selector: #selector(postMessage(notification:)))
    }
    ///Puts the messages received into the array
    @objc
    func postMessage(notification: Notification){
        if notification.object is Message{
            messages.append(notification.object as! Message)
        }else{
            messages.append(.init(timestamp: Date(), message: "Notification received did not have message", source: "AppLogSampleViewModel :: \(#function)"))
        }
    }
}

If your View won't be at the highest level you need to call.

let startListening: AppLogSampleViewModel = .shared

In the ContentView or AppDelegate so the ViewModel starts listening as quickly as possible. You won't necessarily use it for anything but it needs to be called as soon as you want it to start logging messages.

Only the View that shows the messages uses the instance of the ViewModel.

struct AppLogSampleView: View {
    @StateObject var vm: AppLogSampleViewModel = .shared
    //Create this variable anywhere in your app
    private let log = LogManager(name: "AppLogSampleView")
    var body: some View {
        List{
            Button("post", action: {
                //Post like this anywhere in your app
                log.postMessage(message: "random from button")
            })
            DisclosureGroup("log messages"){
                ForEach(vm.messages, content: { message in
                    VStack{
                        Text(message.timestamp.description)
                        Text(message.message)
                        Text(message.source)
                    }
                })
            }
        }
    }
}

Here is the rest of the code you need to get this sample working.

struct AppLogSampleView_Previews: PreviewProvider {
    static var previews: some View {
        AppLogSampleView()
    }
}
extension Notification.Name {
    static let logManagerMessage = Notification.Name("logManagerMessage")
}
struct Message: Identifiable{
    let id: UUID = .init()
    var timestamp: Date
    var message: String
    var source: String
}

Only the one View that shows the messages needs access to the ViewModel and only one ViewModel subscribes to the notifications.

All the other classes and structs will just create an instance of the manager and call the method to post the messages.

There is no sharing/passing between the classes and structs everybody gets their own instance.

Your manager can have as many or as little methods as you want, mine usually mimics the Logger from osLog with log, info, debug and  error methods.

The specific methods call the osLog and 3rd party Analytics Services corresponding methods.

Also, the error method sends a notification that a ViewModel at the top level receives and shows an Alert.

To get all this detail working it takes a lot more code but you have the pattern with the code above.

In your code, in the updateUIViewController you break the single source if truth rule by copying the messages and putting them in another source of truth, right here.

fullLogMessage = logViewModel.getTheFullLogMessage()

This is also done without a check to make sure that you don't go into an infinite loop. Anytime there is code in an update method you should check that the work actually needs to be done. Such as comparing that the new location doesn't already match the old location.


来源: stackexchange

问:
Recursive search JSON/DICT in Python 3
I am realizing in Python 3 some APIs that allow me to receive information about a school based on the class code. But I would like to know how I get the information through the class code.
Example:
I enter the code GF528S and I want the program to tell me the class (3C INF), the address (Address 1, Milan), and if possible also the name of the school (Test School 1) and the previous keys. Thanks in advance! Of course I use a JSON structure:

```<code>{
    "schools": {
         "Lombardia": {
            "Milano": {
                "Milano": {
                    "Test School 1": {
                        "sedi": {
                            "0": {
                                "indirizzo": "Address 1, Milan",
                                "classi": {
                                    "INFORMATICA E TELECOMUNICAZIONI": {
                                        "3C INF": "GF528S"
                                    }
                                }
                            },
                            "1": {
                                "indirizzo": "Address 2, Milan",
                                "classi": {
                                    "INFORMATICA E TELECOMUNICAZIONI": {
                                        "1A IT": "HKPV5P",
                                        "2A IT": "QL3J3K",
                                        "3A INF": "X4E35C",
                                        "3A TEL": "ZAA7LC"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
</code>```

When I get the values from my database they are converted to a python dictionary if it helps!
After a series of tests thanks to your answers, I found that the for in .items() is blocked when it shows the indirizzo field:
In particular, it cannot search in these dictionaries:

```<code>{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'3C INF': 'GF528S'}}, 'indirizzo': 'Address 1, Milan'}
{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'1A IT': 'HKPV5P', '2A IT': 'QL3J3K', '3A INF': 'X4E35C', '3A TEL': 'ZAA7LC'}}, 'indirizzo': 'Address 2, Milan'}
</code>```

I think the problem is precisely the indirizzo field. If you want to do the for first, it can be saved in a variable and deleted from the json:

```<code>del val ["address"]
</code>```

The problem is that then I can't associate the address with the class.
Code:

```<code>def dictionary_check(input):
    indirizzo = ""
    for key,value in input.items():
        if isinstance(value, dict):
            dictionary_check(value)
        else:
            for i in value:
                indirizzo += i["indirizzo"]
                del i['indirizzo']
                for x, y in i.items():
                    for z, j in y.items():
                        for a in j.items():
                            if a[1] == "HKPV5P":
                                print(indirizzo)
                                print("Classe: " + a[0])
</code>```

答:
While I can't write the exact code for you, I think it's reasonable to be able to give you a rough idea of what the code would look like, and some guidance.

I don't exactly know where this JSON data is being obtained. So it may have more / less keys when your applications runs. However, assuming the json is exactly as is, and the json data is loaded onto the variable (let's say json_map), then accessing a specific value looks something like:

```<code>json_map[key_value]
</code>```

So you would want to do something similar to

```<code>json_map['schools']['Lombardia']['Milano']
</code>```

and more keys until you reach the dictionary you want to play around with.

I think the point you might be confused is - if you have multiple values (that you may not be aware of what they might look like) how you handle it. For example, I think the key "sedi" (which I assume means locations) might return multiple locations (i.e. schools) and you won't know what their keys / values are. In that case, you may wish to iterate through that dictionary via something like:

```<code>for key, value in dict_.items():
    # do your action
</code>```

it is likely that key will be an integer (in string format) and value will be another dictionary. You will want to check a specific attribute of the dictionary to see if it's the one you're looking for.

Also, finally, when you get to the 'INFORMATICA E TELECOMUNICAZIONI' dictionary of the location(s), you may wish to return the key of the item that has the corresponding value. Something like:

```<code>for key, value in dict_.items():
    if value == 'GF528S':
        return key
</code>```

Of course, you'll be able to replace this value of 'GF528S' to a variable so you can change it each time.

I think this is as far as I can help you without actually implementing this. I gave the benefit of the doubt that you are like me when I just started programming and I just needed someone to give me a rough outline of what to do. Any more help, I think you may need grab someone who has knowledge of what to do IRL or hire a tutor/teacher to teach you basic concepts of Programming.

ContentLicense: CC BY-SA 4.0

Title: Recursive search JSON/DICT in Python 3

Body:
I am realizing in Python 3 some APIs that allow me to receive information about a school based on the class code. But I would like to know how I get the information through the class code.
Example:
I enter the code GF528S and I want the program to tell me the class (3C INF), the address (Address 1, Milan), and if possible also the name of the school (Test School 1) and the previous keys. Thanks in advance! Of course I use a JSON structure:

{
    "schools": {
         "Lombardia": {
            "Milano": {
                "Milano": {
                    "Test School 1": {
                        "sedi": {
                            "0": {
                                "indirizzo": "Address 1, Milan",
                                "classi": {
                                    "INFORMATICA E TELECOMUNICAZIONI": {
                                        "3C INF": "GF528S"
                                    }
                                }
                            },
                            "1": {
                                "indirizzo": "Address 2, Milan",
                                "classi": {
                                    "INFORMATICA E TELECOMUNICAZIONI": {
                                        "1A IT": "HKPV5P",
                                        "2A IT": "QL3J3K",
                                        "3A INF": "X4E35C",
                                        "3A TEL": "ZAA7LC"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

When I get the values from my database they are converted to a python dictionary if it helps!
After a series of tests thanks to your answers, I found that the for in .items() is blocked when it shows the indirizzo field:
In particular, it cannot search in these dictionaries:

{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'3C INF': 'GF528S'}}, 'indirizzo': 'Address 1, Milan'}
{'classi': {'INFORMATICA E TELECOMUNICAZIONI': {'1A IT': 'HKPV5P', '2A IT': 'QL3J3K', '3A INF': 'X4E35C', '3A TEL': 'ZAA7LC'}}, 'indirizzo': 'Address 2, Milan'}

I think the problem is precisely the indirizzo field. If you want to do the for first, it can be saved in a variable and deleted from the json:

del val ["address"]

The problem is that then I can't associate the address with the class.
Code:

def dictionary_check(input):
    indirizzo = ""
    for key,value in input.items():
        if isinstance(value, dict):
            dictionary_check(value)
        else:
            for i in value:
                indirizzo += i["indirizzo"]
                del i['indirizzo']
                for x, y in i.items():
                    for z, j in y.items():
                        for a in j.items():
                            if a[1] == "HKPV5P":
                                print(indirizzo)
                                print("Classe: " + a[0])

Body:
While I can't write the exact code for you, I think it's reasonable to be able to give you a rough idea of what the code would look like, and some guidance.

I don't exactly know where this JSON data is being obtained. So it may have more / less keys when your applications runs. However, assuming the json is exactly as is, and the json data is loaded onto the variable (let's say json_map), then accessing a specific value looks something like:

json_map[key_value]

So you would want to do something similar to

json_map['schools']['Lombardia']['Milano']

and more keys until you reach the dictionary you want to play around with.

I think the point you might be confused is - if you have multiple values (that you may not be aware of what they might look like) how you handle it. For example, I think the key "sedi" (which I assume means locations) might return multiple locations (i.e. schools) and you won't know what their keys / values are. In that case, you may wish to iterate through that dictionary via something like:

for key, value in dict_.items():
    # do your action

it is likely that key will be an integer (in string format) and value will be another dictionary. You will want to check a specific attribute of the dictionary to see if it's the one you're looking for.

Also, finally, when you get to the 'INFORMATICA E TELECOMUNICAZIONI' dictionary of the location(s), you may wish to return the key of the item that has the corresponding value. Something like:

for key, value in dict_.items():
    if value == 'GF528S':
        return key

Of course, you'll be able to replace this value of 'GF528S' to a variable so you can change it each time.

I think this is as far as I can help you without actually implementing this. I gave the benefit of the doubt that you are like me when I just started programming and I just needed someone to give me a rough outline of what to do. Any more help, I think you may need grab someone who has knowledge of what to do IRL or hire a tutor/teacher to teach you basic concepts of Programming.


问:
Accessing List Value by looking up value with same index
I was following this blog post:
https://www.robert-hickman.eu/post/dixon_coles_1/

And in a number of places, he gets a value from a list by putting in a value with the equivalent index, rather like using it as a key in a python dictionary. This would be an example in the link:

What I understand he's done is basically this:

```<code>
teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)
example_list <- as.list(example_df)

example_list$values[a]

Error: object 'a' not found

</code>```

But I get an NA value for this - am I missing something ?

Thanks in advance !

答:
The way a list works in R, makes it not really practical to address a list like that, as the values in the list aren't associated like that.
Which leads to this:

```<code>teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)
example_list <- as.list(example_df)

#Gives NULL
example_list[example_list$teams == "a"]$values

#Gives 1, 2, 3
example_list[example_list$teams == "b"]$values

#Gives NULL
example_list[example_list$teams == "b"]$values
</code>```

You can see that this wouldn't work, because the syntax you would expect to work in this case, throws an error "incorrect amount of dimensions":

```<code>example_list[example_list$teams == "b", ]$values
</code>```

However, it is really easy to address a data frame, or any matrix like structure in the way you want to:

```<code>teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)

#Gives 1
example_df[example_df$teams == "a", ]$values

#Gives 2
example_df[example_df$teams == "b", ]$values

#Gives 3
example_df[example_df$teams == "b", ]$values
</code>```

What I think is happening in the tutorial you shared is something else. As far as I can see, there are no names passed through to the list, but variables. It is not giving the value of a higher dimensional thing, but rather the value of the list itself.
That also makes a lot more sense, as that is what the syntax is doing. "teams[1]" Simply returns the first value in the list called "teams" (even if that value is a vector or whatever) Of course, teams[i], where i is a variable, also works. What I mean is this:

```<code>teams = list(A = 1, B = 2, C = 3, D = 4)

#Gives A
teams[1]
</code>```

If you want to understand why one of them works and the other one doesn't, here is both together. Throw it in RStudio, and look through the Environment.

```<code>## One dimensional
teams = list(A = "a", B = "very", C = "good", D = "example")

#Gives "very"
teams[2]

## Two dimensional
teams  <- c("a","b","c")
values <- c(1,2,3)
teams2 <- list(teams, values)

#Gives "a, b, c"
teams2[1]

#Gives NULL
teams2[3]
</code>```

Body:
I was following this blog post:
https://www.robert-hickman.eu/post/dixon_coles_1/

And in a number of places, he gets a value from a list by putting in a value with the equivalent index, rather like using it as a key in a python dictionary. This would be an example in the link:

What I understand he's done is basically this:

teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)
example_list <- as.list(example_df)

example_list$values[a]

Error: object 'a' not found

But I get an NA value for this - am I missing something ?

Thanks in advance !

Body:
The way a list works in R, makes it not really practical to address a list like that, as the values in the list aren't associated like that.
Which leads to this:

teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)
example_list <- as.list(example_df)

#Gives NULL
example_list[example_list$teams == "a"]$values

#Gives 1, 2, 3
example_list[example_list$teams == "b"]$values

#Gives NULL
example_list[example_list$teams == "b"]$values

You can see that this wouldn't work, because the syntax you would expect to work in this case, throws an error "incorrect amount of dimensions":

example_list[example_list$teams == "b", ]$values

However, it is really easy to address a data frame, or any matrix like structure in the way you want to:

teams <- c("a","b","c")
values <- c(1,2,3)

example_df <- data.frame(teams,values)

#Gives 1
example_df[example_df$teams == "a", ]$values

#Gives 2
example_df[example_df$teams == "b", ]$values

#Gives 3
example_df[example_df$teams == "b", ]$values

What I think is happening in the tutorial you shared is something else. As far as I can see, there are no names passed through to the list, but variables. It is not giving the value of a higher dimensional thing, but rather the value of the list itself.
That also makes a lot more sense, as that is what the syntax is doing. "teams[1]" Simply returns the first value in the list called "teams" (even if that value is a vector or whatever) Of course, teams[i], where i is a variable, also works. What I mean is this:

teams = list(A = 1, B = 2, C = 3, D = 4)

#Gives A
teams[1]

If you want to understand why one of them works and the other one doesn't, here is both together. Throw it in RStudio, and look through the Environment.

## One dimensional
teams = list(A = "a", B = "very", C = "good", D = "example")

#Gives "very"
teams[2]

## Two dimensional
teams  <- c("a","b","c")
values <- c(1,2,3)
teams2 <- list(teams, values)

#Gives "a, b, c"
teams2[1]

#Gives NULL
teams2[3]


问:
How to query by multiple conditions in faunadb?
I try to improve my understanding of FaunaDB.

I have a collection that contains records like:

```<code>{
  "ref": Ref(Collection("regions"), "261442015390073344"),
  "ts": 1587576285055000,
  "data": {
    "name": "italy",
    "attributes": {
      "amenities": {
        "camping": 1,
        "swimming": 7,
        "hiking": 3,
        "culture": 7,
        "nightlife": 10,
        "budget": 6
      }
    }
  }
}
</code>```

I would like to query in a flexible way by different attributes like:

data.attributes.amenities.camping > 5

data.attributes.amenities.camping > 5 AND data.attributes.amenities.hiking > 6

data.attributes.amenities.camping < 6 AND data.attributes.amenities.culture > 6 AND hiking > 5 AND ...

I created an index containing all attributes, but I don't know how to do greater equals filtering in an index that contains multiple terms.

My fallback would be to create an index for each attribute and use Intersection to get the records that are in all subqueries that I want to check, but this feels somehow wrong:

The query: budget >= 6 AND camping >=8 would be:

```<code>Index:
{
  name: "all_regions_by_all_attributes",
  unique: false,
  serialized: true,
  source: "regions",
  terms: [],
  values: [
    {
      field: ["data", "attributes", "amenities", "culture"]
    },
    {
      field: ["data", "attributes", "amenities", "hiking"]
    },
    {
      field: ["data", "attributes", "amenities", "swimming"]
    },
    {
      field: ["data", "attributes", "amenities", "budget"]
    },
    {
      field: ["data", "attributes", "amenities", "nightlife"]
    },
    {
      field: ["data", "attributes", "amenities", "camping"]
    },
    {
      field: ["ref"]
    }
  ]
}
</code>```

Query:

```<code>Map(
  Paginate(
    Intersection(
      Range(Match(Index("all_regions_by_all_attributes")), [0, 0, 0, 6, 0, 8], [10, 10, 10, 10, 10, 10]),
    )

  ),
  Lambda(
    ["culture", "hiking", "swimming", "budget", "nightlife", "camping", "ref"],
    Get(Var("ref"))
  )
)
</code>```

This approach has the following disadvantages:

It does not work like expected, if for example the first (culture) attribute is in this range, but the second (hiking) not, then I would still get a return values

It causes a lot of reads due to the reference that I need to follow for each result.

Is it possible to store all values in this kind of index that would contain all the data? I know I can just add more values to the index and access them. But this would mean I have to create a new index as soon as we add more fields to the entity. But maybe this is a common thing.

thanks in advance

答:
Here is the another variant of filtering, in SQL looks like:

SELECT * FROM clients WHERE salary > 2000 AND age > 30;

For fauna query:

const response = await client.query(
  q.Let(
    {
      allClients: q.Match(q.Index("allClients")),

      filteredClients: q.Filter(
        q.Var("allClients"),
        q.Lambda(
          "client",
          q.And(
            q.GT(q.Select(["data", "salary"], q.Get(q.Var("client"))), 2000),
            q.GT(q.Select(["data", "age"], q.Get(q.Var("client"))), 30)
          )
        )
      ),

      paginatedDocuments: q.Map(
        q.Paginate(q.Var("filteredClients")),
        q.Lambda("x", q.Get(q.Var("x")))
      ),
      total: q.Count(q.Var("filteredClients"))
    },

    {
      documents: q.Var("paginatedDocuments"),
      total: q.Var("total")
    }
  )
);```
</div>
</div>
</p>
<p>This is some kind of <strong>filtering in javascript</strong> where the condition if returns true so it will be in the result of the response. Example:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const filteredClients = allClients.filter((client) => {
  const { salary, age } = client;

  return ( salary > 2000 ) && (age > 30)
})</code>```

Body:
I try to improve my understanding of FaunaDB.

I have a collection that contains records like:

{
  "ref": Ref(Collection("regions"), "261442015390073344"),
  "ts": 1587576285055000,
  "data": {
    "name": "italy",
    "attributes": {
      "amenities": {
        "camping": 1,
        "swimming": 7,
        "hiking": 3,
        "culture": 7,
        "nightlife": 10,
        "budget": 6
      }
    }
  }
}

I would like to query in a flexible way by different attributes like:

data.attributes.amenities.camping > 5

data.attributes.amenities.camping > 5 AND data.attributes.amenities.hiking > 6

data.attributes.amenities.camping < 6 AND data.attributes.amenities.culture > 6 AND hiking > 5 AND ...

I created an index containing all attributes, but I don't know how to do greater equals filtering in an index that contains multiple terms.

My fallback would be to create an index for each attribute and use Intersection to get the records that are in all subqueries that I want to check, but this feels somehow wrong:

The query: budget >= 6 AND camping >=8 would be:

Index:
{
  name: "all_regions_by_all_attributes",
  unique: false,
  serialized: true,
  source: "regions",
  terms: [],
  values: [
    {
      field: ["data", "attributes", "amenities", "culture"]
    },
    {
      field: ["data", "attributes", "amenities", "hiking"]
    },
    {
      field: ["data", "attributes", "amenities", "swimming"]
    },
    {
      field: ["data", "attributes", "amenities", "budget"]
    },
    {
      field: ["data", "attributes", "amenities", "nightlife"]
    },
    {
      field: ["data", "attributes", "amenities", "camping"]
    },
    {
      field: ["ref"]
    }
  ]
}

Query:

Map(
  Paginate(
    Intersection(
      Range(Match(Index("all_regions_by_all_attributes")), [0, 0, 0, 6, 0, 8], [10, 10, 10, 10, 10, 10]),
    )

  ),
  Lambda(
    ["culture", "hiking", "swimming", "budget", "nightlife", "camping", "ref"],
    Get(Var("ref"))
  )
)

This approach has the following disadvantages:

It does not work like expected, if for example the first (culture) attribute is in this range, but the second (hiking) not, then I would still get a return values

It causes a lot of reads due to the reference that I need to follow for each result.

Is it possible to store all values in this kind of index that would contain all the data? I know I can just add more values to the index and access them. But this would mean I have to create a new index as soon as we add more fields to the entity. But maybe this is a common thing.

thanks in advance

Body:
Here is the another variant of filtering, in SQL looks like:

SELECT * FROM clients WHERE salary > 2000 AND age > 30;

For fauna query:

const response = await client.query(
  q.Let(
    {
      allClients: q.Match(q.Index("allClients")),

      filteredClients: q.Filter(
        q.Var("allClients"),
        q.Lambda(
          "client",
          q.And(
            q.GT(q.Select(["data", "salary"], q.Get(q.Var("client"))), 2000),
            q.GT(q.Select(["data", "age"], q.Get(q.Var("client"))), 30)
          )
        )
      ),

      paginatedDocuments: q.Map(
        q.Paginate(q.Var("filteredClients")),
        q.Lambda("x", q.Get(q.Var("x")))
      ),
      total: q.Count(q.Var("filteredClients"))
    },

    {
      documents: q.Var("paginatedDocuments"),
      total: q.Var("total")
    }
  )
);

This is some kind of filtering in javascript where the condition if returns true so it will be in the result of the response. Example:

const filteredClients = allClients.filter((client) => {
  const { salary, age } = client;

  return ( salary > 2000 ) && (age > 30)
})


问:
Linking to different areas on a page
This may seem like a stupid question, but:

So what i would like to do is set up a menu section so that when the user clicked on the title of the section it would send them to that particular spot on the page with out having to scoll down. I am not entirely sure how this would work or how complicated it is to achieve.

So bacially i would have

Menu

item one (be a link)

item two (be a link)

etc (be a link)

then further down the page

item one (when item one in menu is clicked page comes to here)

"details about it here"

item two (when item two in menu is clicked page comes to here)

"details here"

How exactly would i go about doing this?

Any help or suggestions are greatly appreciated. Thanks.

答:
You can do this with anchor tags.

In the menu:

```<code><a href="#item-one">item one</a>
<a href="#item-two">item two</a>
</code>```

Further down the page:

```<code><a name="item-one">item one</a>
</code>```

...

```<code><a name="item-two">item two</a>
</code>```

You can check out http://www.w3schools.com/HTML/html_links.asp for more information.

ContentLicense: CC BY-SA 3.0

Title: Linking to different areas on a page

Body:
You can do this with anchor tags.

In the menu:

<a href="#item-one">item one</a>
<a href="#item-two">item two</a>

Further down the page:

<a name="item-one">item one</a>

...

<a name="item-two">item two</a>

You can check out http://www.w3schools.com/HTML/html_links.asp for more information.


问:
How do i make the bot to add reaction to every message send in a specific channel?
Ive been trying to make this work but the bot won't react to messages in that specific channel.

the code:

```<code>from nextcord.ext import commands

class React(commands.Cog, name="React"):
    def __init__(self, bot:commands.Bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_message_send(self, message):
        channel = 925073325066178570
        if message.channel.id == channel:
            await message.add_reaction("⬆")

def setup(bot: commands.Bot):
    bot.add_cog(React(bot))
</code>```

there is no error detected by the code editor.

答:
You can do the following:</p>
```<code>@commands.Cog.listener()
async def on_message(self, message):
    channel = await self.bot.fetch_channel(Your channel ID)
    if message.channel.id == channel:
        await message.add_reaction("⬆")
</code>```

Body:
Ive been trying to make this work but the bot won't react to messages in that specific channel.

the code:

from nextcord.ext import commands

class React(commands.Cog, name="React"):
    def __init__(self, bot:commands.Bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_message_send(self, message):
        channel = 925073325066178570
        if message.channel.id == channel:
            await message.add_reaction("⬆")

def setup(bot: commands.Bot):
    bot.add_cog(React(bot))

there is no error detected by the code editor.

Body:
You can do the following:

@commands.Cog.listener()
async def on_message(self, message):
    channel = await self.bot.fetch_channel(Your channel ID)
    if message.channel.id == channel:
        await message.add_reaction("⬆")


问:
How to disable spell check popup in Ms Word?
When you click red lined uncorrect text appears a popup that includes some predictions but it's very annoying, how to close it?

答: Go to Review > Language > Set Proofing Language and select Do not check spelling or grammar in the popup.


问:
Cannot get simple beginners app to work on tablet using the latest version of Unity
I am new to unity 2021.2.10f and I have become stuck on getting a simple app working on a tablet /real hardware.
I am using unity 2021.2.10f my project is simply the built in
"3D Sample Scene(URP)" I did not change anything to it except added an icon to it (so I can see it in the tablet menu  when it is installed on the android tablet)- the unity project can easily be
recreated-I could not upload it since it the project was large (more than 350MB) for my internet connection.

This is how the  the unity project looks on my computer

enter image description here

When I compile this to an android apk I just get a pink/magenta screen (as shown below).

enter image description here

I also get the message below from the tablet.

enter image description here

After googling around for an answer I found out
this pink/magenta screen means it is a shader problem.After more googling for an answer it was recommended to tick or untick to reset the
~"Auto Graphic API" as a fix-but this did not work for me.
I also changed the color space from Gamma to linear-and again this did not work for me. My tablet is a Maitai MT107.

So my question is -how do I get this to work?
In previous years and using  older versions of unity I have been able to get unity made apps to work perfectly on several different tablets (though not an MT-107).

Also the compiled version of this project does not
work in latest version of Bluestacks on Windows 10-it shows a blank black screen instead of a pink screen-may be it is related to that-
maybe if I can get it to work with the Bluestacks emulator it will work on real hardware-but I do not know what exactly the problem is that is stopping the app working on the MT107.

答:
I figured it out using Shingo's comments.
My tablet only supports GL ES2 because
I ran CPU-Z to find that out.
I made a simple test program (just the default empty project with the blue sky)  with
unity 2020 (NOT the latest version) when GL ES 2 is selected.

Here is the gotcha-it looks like ES2 was removed in the latest version
of Unity 2021.2.10f-but it can be selected in the following way.
I started off by making my test program in unity 2020 save and closed the project. I selected GLES 2, as shown below,in this older version of unity (NOT using "Auto Graphic API")

Then I re-opened it, this makes unity convert the project so it
works in the latest version of unity 2021.2.10f-then I can see the GLES 2 (depreciated) appears in the
latest version of Unity. The GLES2 option circled in blue shown below

-GLES 2 support does not appear in the project if the project is not converted from the older version of unity.

Now I can use the latest version of unity to use with a tablet that supports
only GLES 2 by adding to the empty test program to eventually write my complete program.

I am happy I can still use my tablet with unity because:  it wasn't cheap to
buy and bought this year, if it works on this tablet it will work on a GLES3 tablet (because of backwards compatiability).


问:
How to get an element where the attribute by which I select it can change in Selenium Webdriver C#?
I want to get the src attribute of some elements like this:

```<code>    <div class="product-tile restored" data-v-27bc931c=""><a href="/p/apple-iphone-11-pro/R1NFM0000000T7"
        class="product-tile__link">
        <div class="product-tile__image product-img-front">
            <img alt="Apple  iPhone 11 Pro"
                data-src="/img?width=300&height=300&action=resize&url=/catalog/product/6/f/6f7466aef1ae14ee4fe9764531ef69a1.jpg"
                src="/img?width=300&height=300&action=resize&url=/catalog/product/6/f/6f7466aef1ae14ee4fe9764531ef69a1.jpg"
                lazy="loaded">
            <div class="image-loading"></div>
            <!---->
        </div>
        <div class="product-tile__description">
            <div title=" iPhone 11 Pro" class="product-tile__name"><span class="product-tile__brand">Apple</span> iPhone
                11 Pro
            </div>
            <!---->
        </div>
        <div class="product-tile__footer">
            <div class="product-tile__condition">
                <div>Various conditions<span class="colors"><span class="dot">•</span>4 Colors</span></div>
            </div>
            <div class="product-tile__price">
                <div class="price" data-v-678b2a80="">
                    <div class="current-price" data-v-678b2a80="">
                        <div class="from" data-v-678b2a80="">from</div>
                        <div data-testid="productPrice" class="amount" data-v-678b2a80="">
                            $647.00
                        </div>
                    </div>
                    <div data-v-678b2a80=""><span class="amount amount--del" data-v-678b2a80="">$1049.00</span> <span
                            class="amount amount--save" data-v-678b2a80="">Save
                            $402.00</span></div>
                </div>
            </div>
        </div>
        <div class="product-tile__loading"></div>
    </a>
    <!---->
</div>
</code>```

I'm using driver.FindElement(By.CssSelector("img[lazy='loaded")) but the problem is that this attribute can also be loading. When I try driver.FindElement(By.TagName("img")) that doesn't work.

I don't want to use Try and Catch. How to can I get the src? Here is the website that i want to scrape

答:
To consider both the cases, when value of lazy attribute is loaded and loading, you can use comma seperated values for the css-selectors and use the following locator strategy:

```<code>driver.FindElement(By.CssSelector("img[lazy='loaded'], img[lazy='loading']"))
</code>```

References

You can find a couple of relevant detailed discussions in:

Any built-in way for branching waits with OR conditions?

WebDriverWait for multiple conditions (OR logical evaluation)

selenium two xpath tests in one

Body:
I want to get the src attribute of some elements like this:

Apple iPhone
                11 Pro

Various conditions•4 Colors

from

                            $647.00

$1049.00 Save
                            $402.00

I'm using driver.FindElement(By.CssSelector("img[lazy='loaded")) but the problem is that this attribute can also be loading. When I try driver.FindElement(By.TagName("img")) that doesn't work.

I don't want to use Try and Catch. How to can I get the src? Here is the website that i want to scrape

Body:
To consider both the cases, when value of lazy attribute is loaded and loading, you can use comma seperated values for the css-selectors and use the following locator strategy:

driver.FindElement(By.CssSelector("img[lazy='loaded'], img[lazy='loading']"))

References

You can find a couple of relevant detailed discussions in:

Any built-in way for branching waits with OR conditions?

WebDriverWait for multiple conditions (OR logical evaluation)

selenium two xpath tests in one


问:
How can I stop cin from skippping a line?
I was trying to make a program where the user is asked to give an input and it gives output with answered questions. Everything looks alright except that cin skipped my last question about school.

This is the original code:

//this program fills my data in profile

#include <iostream>
#include <string>

using namespace std;

int main () {

    int age, exp_years;
    char desired_grade;
    string school_name, name;
    const int year_grad = 4;
    bool is_student;

    cout << "You will need to enter your data for portfolio card" << endl;
    cout << "Enter your last name" << endl;
    cin >> name;
    cout << "Enter your age" << endl;
    cin >> age;
    cout << "Enter your years of work experience" << "\n";
    cin >> exp_years;
    cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
    cin >> is_student;
    cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
    cin >> school_name;

     /* trying to make a function below */

    cout << "Awesome, here is your info" << endl << "Your last name is "<< name << endl <<"You are "<<age << " years old." << endl << exp_years << " years of work experience" << endl;
    if ( is_student == 1)
    {
        cout << school_name << " is lucky to have you!\n";
        return 0;
    } else {
        cout << "Btw I am sure that " << school_name << " would be happy to have you as their student anytime\n";
        return 0;
    }

    return 0;
}
```
<p>I read some article and they said that <code>getline()</code> can help, so I tried to substitute with:</p>
```cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
getline(cin, is_student);
cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
getline(cin, school_name);
```

Hovewer, it gives me an error:

error: no matching function for call to 'getline'

What am I missing?

答:
It seems the problem is related to entering a boolean value.

Here is shown how to enter boolean values

```<code>#include <iostream>
#include <iomanip>

int main()
{
    bool is_student;

    std::cin >> is_student;   // accepts 1 as true or 0 as false
    std::cout << is_student << '\n';

    std::cin >> std::boolalpha >> is_student;  // accepts strings false or true
    std::cout << is_student << '\n';
}
</code>```

Body:
I was trying to make a program where the user is asked to give an input and it gives output with answered questions. Everything looks alright except that cin skipped my last question about school.

This is the original code:

//this program fills my data in profile

#include <iostream>
#include <string>

using namespace std;

int main () {

    int age, exp_years;
    char desired_grade;
    string school_name, name;
    const int year_grad = 4;
    bool is_student;

    cout << "You will need to enter your data for portfolio card" << endl;
    cout << "Enter your last name" << endl;
    cin >> name;
    cout << "Enter your age" << endl;
    cin >> age;
    cout << "Enter your years of work experience" << "\n";
    cin >> exp_years;
    cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
    cin >> is_student;
    cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
    cin >> school_name;

     /* trying to make a function below */

    cout << "Awesome, here is your info" << endl << "Your last name is "<< name << endl <<"You are "<<age << " years old." << endl << exp_years << " years of work experience" << endl;
    if ( is_student == 1)
    {
        cout << school_name << " is lucky to have you!\n";
        return 0;
    } else {
        cout << "Btw I am sure that " << school_name << " would be happy to have you as their student anytime\n";
        return 0;
    }

    return 0;
}

I read some article and they said that getline() can help, so I tried to substitute with:

cout << "Is it true or false that you are a student (put 'true' or 'false')" << endl;
getline(cin, is_student);
cout << "Great! What school are you in (if you are not a student put desirable school)?" << endl;
getline(cin, school_name);

Hovewer, it gives me an error:

error: no matching function for call to 'getline'

What am I missing?

Body:
It seems the problem is related to entering a boolean value.

Here is shown how to enter boolean values

#include <iostream>
#include <iomanip>

int main()
{
    bool is_student;

    std::cin >> is_student;   // accepts 1 as true or 0 as false
    std::cout << is_student << '\n';

    std::cin >> std::boolalpha >> is_student;  // accepts strings false or true
    std::cout << is_student << '\n';
}


问:
How to make MySQL / Sequelize query join
I have 2 models, User and Message, and an index and I'm looking to create a get request statement that would return all messages where ....

I (sender_id) sent the user messages and the other user (receiver_id)received.

The other user (sender_id) sent the message and I (receiver_id) received it.

and then somehow join those together so that I can display a chain of messages by created_at

but I'm new to all of this and struggling to figure this out.

```<code>var User = db.seq.define('User',{
    id: {type: db.Sequelize.INTEGER},
    username: { type: db.Sequelize.STRING},
    email: { type: db.Sequelize.STRING},
    password: { type: db.Sequelize.STRING},

});

var Message= db.seq.define('Message',{
    id: {type: db.Sequelize.INTEGER},
    receiver_id: { type: db.Sequelize.INTEGER},
    message_text: { type: db.Sequelize.STRING},

});

User.hasMany(Message, {
    foreignKey: 'sender_id'
});

Message.belongsTo(User, {
    foreignKey: 'sender_id'
});
</code>```

Basically I'm looking to setup something like this... but I'm sure I'm doing this all wrong and probably should use sequelize literal but struggling with that as well

```<code>  Message.findAll({
    where: {
      [Op.or]: [
        // grab user id from the session data
        { receiver_id: req.session.user_id },
        { sender_id: req.params.id },
      ],
      [Op.or]: [
        // grab user id from the session data
        { receiver_id: req.params.id },
        { sender_id: req.session.user_id },
      ],
    },
    attributes: ['id', 'message_text', 'created_at'],
    // display newest messages first
    order: [['created_at', 'DESC']],
    include: [
      {
        model: User,
      },
    ],
  })
</code>```

答:
First I don't see sender_id field definition in the Message model though I see receiver_id and they both should be explicitly defined or just mentioned in associations or be implicitly named by Sequelize if omitted in associations.

Second, you definitely need one more association from Message to User to get a receiver as a user for a certain message (if you want it of course). In the case you want it you need to indicate aliases for both associations to distinguish sender and receiver users:

Message.belongsTo(User, {
    foreignKey: 'sender_id'
    as: 'Sender'
});
Message.belongsTo(User, {
    foreignKey: 'receiver_id'
    as: 'Receiver'
});
```
<p>The same goes for other end associations as well:</p>
<pre class="lang-js prettyprint-override"><code>User.hasMany(Message, {
    foreignKey: 'sender_id',
    as: 'SentMessages'
});
User.hasMany(Message, {
    foreignKey: 'receiver_id',
    as: 'ReceivedMessages'
});
</code>```

Third, you need to correct conditions in the where option according to what you described:

Message.findAll({
    where: {
      [Op.or]: [
        {
         // these two conditions will be joined by AND
         // grab user id from the session data
         receiver_id: req.session.user_id,
         sender_id: req.params.id
        },
        {
          // these two conditions will be joined by AND
          // grab user id from the session data
          receiver_id: req.params.id,
          sender_id: req.session.user_id
        },
      ],
    },
    attributes: ['id', 'message_text', 'created_at'],
    // display newest messages first
    order: [['created_at', 'DESC']],
    include: [
      {
        model: User,
        // don't forget to indicate a certain alias depending on what user you wish to get here
        as: 'Sender'
      },
    ],
  })
```

Body:
I have 2 models, User and Message, and an index and I'm looking to create a get request statement that would return all messages where ....

I (sender_id) sent the user messages and the other user (receiver_id)received.

The other user (sender_id) sent the message and I (receiver_id) received it.

and then somehow join those together so that I can display a chain of messages by created_at

but I'm new to all of this and struggling to figure this out.

var User = db.seq.define('User',{
    id: {type: db.Sequelize.INTEGER},
    username: { type: db.Sequelize.STRING},
    email: { type: db.Sequelize.STRING},
    password: { type: db.Sequelize.STRING},

});

var Message= db.seq.define('Message',{
    id: {type: db.Sequelize.INTEGER},
    receiver_id: { type: db.Sequelize.INTEGER},
    message_text: { type: db.Sequelize.STRING},

});

User.hasMany(Message, {
    foreignKey: 'sender_id'
});

Message.belongsTo(User, {
    foreignKey: 'sender_id'
});

Basically I'm looking to setup something like this... but I'm sure I'm doing this all wrong and probably should use sequelize literal but struggling with that as well

  Message.findAll({
    where: {
      [Op.or]: [
        // grab user id from the session data
        { receiver_id: req.session.user_id },
        { sender_id: req.params.id },
      ],
      [Op.or]: [
        // grab user id from the session data
        { receiver_id: req.params.id },
        { sender_id: req.session.user_id },
      ],
    },
    attributes: ['id', 'message_text', 'created_at'],
    // display newest messages first
    order: [['created_at', 'DESC']],
    include: [
      {
        model: User,
      },
    ],
  })

Body:
First I don't see sender_id field definition in the Message model though I see receiver_id and they both should be explicitly defined or just mentioned in associations or be implicitly named by Sequelize if omitted in associations.

Second, you definitely need one more association from Message to User to get a receiver as a user for a certain message (if you want it of course). In the case you want it you need to indicate aliases for both associations to distinguish sender and receiver users:

Message.belongsTo(User, {
    foreignKey: 'sender_id'
    as: 'Sender'
});
Message.belongsTo(User, {
    foreignKey: 'receiver_id'
    as: 'Receiver'
});

The same goes for other end associations as well:

User.hasMany(Message, {
    foreignKey: 'sender_id',
    as: 'SentMessages'
});
User.hasMany(Message, {
    foreignKey: 'receiver_id',
    as: 'ReceivedMessages'
});

Third, you need to correct conditions in the where option according to what you described:

Message.findAll({
    where: {
      [Op.or]: [
        {
         // these two conditions will be joined by AND
         // grab user id from the session data
         receiver_id: req.session.user_id,
         sender_id: req.params.id
        },
        {
          // these two conditions will be joined by AND
          // grab user id from the session data
          receiver_id: req.params.id,
          sender_id: req.session.user_id
        },
      ],
    },
    attributes: ['id', 'message_text', 'created_at'],
    // display newest messages first
    order: [['created_at', 'DESC']],
    include: [
      {
        model: User,
        // don't forget to indicate a certain alias depending on what user you wish to get here
        as: 'Sender'
      },
    ],
  })


问:
For loop in function to move the item of the list
I want to move the negative numbers to the end of the list until I encounter the positive number.

List:

```<code>a=[-1,-2,2,3,4,-5]
</code>```

The result i want:

```<code>[-2, 2, 3, 4, -5, -1]
[2, 3, 4, -5, -1, -2]
</code>```

My function:

```<code>def f1(A):
  for i in A:
    if i>=0:
      break
    if 'Z' not in globals() or 'Z' not in locals():
     X=A
     X1=X[0]
     X.remove(X1)
     X.append(X1)
     Z=X
    else:
      X=Z
      X1=X[0]
      X.remove(X1)
      X.append(X1)
      Z=X
    print(Z)

a=[-1,-2,2,3,4,-5]
print (f1 (a))
</code>```

But the result

```<code>[-2, 2, 3, 4, -5, -1]
None
</code>```

can we solve it with this function?

答:
You asked to move the negative numbers to the end of the list a until encountering the first positive number. To actually move them in your list, meaning to "mutate" the list in place, you could do something like this:

```<code>def rotateInPlaceToFirstPositive(a):
    n = len(a)
    p = 0
    while p < n and a[p] < 0:
        p += 1
    if p < n:
        b = a[:p]
        for i in range(n - p):
            a[i] = a[i + p]
        for i in range(p):
            a[n - p + i] = b[i]
</code>```

You can use this function like this:

```<code>a = [-1,-2,2,3,4,-5]
rotateInPlaceToFirstPositive(a)
print(a)
# prints: [2, 3, 4, -5, -1, -2]
</code>```

However, if you prefer to leave a unchanged and return a separate list that has the desired result, you can just do this:

```<code>def rotateToFirstPositive(a):
    n = len(a)
    p = 0
    while p < n and a[p] < 0:
        p += 1
    if p < n:
        a = a[p:] + a[:p]
    return a
</code>```

Now, you will see this behavior when you call the function:

```<code>a = [-1,-2,2,3,4,-5]
print(rotateToFirstPositive(a))
# prints: [2, 3, 4, -5, -1, -2]
</code>```

Body:
I want to move the negative numbers to the end of the list until I encounter the positive number.

List:

a=[-1,-2,2,3,4,-5]

The result i want:

[-2, 2, 3, 4, -5, -1]
[2, 3, 4, -5, -1, -2]

My function:

def f1(A):
  for i in A:
    if i>=0:
      break
    if 'Z' not in globals() or 'Z' not in locals():
     X=A
     X1=X[0]
     X.remove(X1)
     X.append(X1)
     Z=X
    else:
      X=Z
      X1=X[0]
      X.remove(X1)
      X.append(X1)
      Z=X
    print(Z)

a=[-1,-2,2,3,4,-5]
print (f1 (a))

But the result

[-2, 2, 3, 4, -5, -1]
None

can we solve it with this function?

Body:
You asked to move the negative numbers to the end of the list a until encountering the first positive number. To actually move them in your list, meaning to "mutate" the list in place, you could do something like this:

def rotateInPlaceToFirstPositive(a):
    n = len(a)
    p = 0
    while p < n and a[p] < 0:
        p += 1
    if p < n:
        b = a[:p]
        for i in range(n - p):
            a[i] = a[i + p]
        for i in range(p):
            a[n - p + i] = b[i]

You can use this function like this:

a = [-1,-2,2,3,4,-5]
rotateInPlaceToFirstPositive(a)
print(a)
# prints: [2, 3, 4, -5, -1, -2]

However, if you prefer to leave a unchanged and return a separate list that has the desired result, you can just do this:

def rotateToFirstPositive(a):
    n = len(a)
    p = 0
    while p < n and a[p] < 0:
        p += 1
    if p < n:
        a = a[p:] + a[:p]
    return a

Now, you will see this behavior when you call the function:

a = [-1,-2,2,3,4,-5]
print(rotateToFirstPositive(a))
# prints: [2, 3, 4, -5, -1, -2]


问:
Pyspark Dataframe to AWS MySql: requirement failed: The driver could not open a JDBC connection
I want to write a pyspark dataframe into a MySQL table in AWS RDS, but I keep getting the error

```<code>pyspark.sql.utils.IllegalArgumentException: requirement failed: The driver could not open a JDBC connection. Check the URL: jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com
</code>```

My code looks like this:

```<code>import os
import sys

spark = SparkSession.builder\
            .appName('test-app')\
            .config('spark.jars.packages', 'mysql:mysql-connector-java:8.0.28')\
            .getOrCreate()

properties = {'user':'admin', 'password':'password', 'driver':'com.mysql.cj.jdbc.Driver'}
resultDF.write.jdbc(url='jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com', table='mcm_objects', properties=properties)\
            .mode('append')\
            .save()
</code>```

I also tried the url 'jdbc:mysql://mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com',
but then I get the error:

```<code>java.sql.SQLException: No database selected
</code>```

No idea what I am doing wrong. Any help would be greatly appreciated

答:
table should be {dbName}.{dbtable}:

```<code>resultDF.write.jdbc(url='jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com', table='{dbname}.mcm_objects', properties=properties)\
            .mode('append')\
            .save()
</code>```

Body:
I want to write a pyspark dataframe into a MySQL table in AWS RDS, but I keep getting the error

pyspark.sql.utils.IllegalArgumentException: requirement failed: The driver could not open a JDBC connection. Check the URL: jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com

My code looks like this:

import os
import sys

spark = SparkSession.builder\
            .appName('test-app')\
            .config('spark.jars.packages', 'mysql:mysql-connector-java:8.0.28')\
            .getOrCreate()

properties = {'user':'admin', 'password':'password', 'driver':'com.mysql.cj.jdbc.Driver'}
resultDF.write.jdbc(url='jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com', table='mcm_objects', properties=properties)\
            .mode('append')\
            .save()

I also tried the url 'jdbc:mysql://mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com',
but then I get the error:

java.sql.SQLException: No database selected

No idea what I am doing wrong. Any help would be greatly appreciated

Body:
table should be {dbName}.{dbtable}:

resultDF.write.jdbc(url='jdbc:mysql:mtestdb.ch4i3d3jc0yc.eu-central-1.rds.amazonaws.com', table='{dbname}.mcm_objects', properties=properties)\
            .mode('append')\
            .save()


问:
MVC3 "Dynamic" Parameter List Model and View
Need a hand/guide of creating a view that handles a list of parameters which we get the name of during run time, currently during the postback it just won't return anything, using the MVC html helpers.

My Models

```<code>public class Parameter {
  public string Name {get; set;}
  public string Value {get; set;}
}

public class Job {
  public List<Parameter> parameters {get; set;}
}
</code>```

My Views

Add View

```<code>@model Models.Job
@using (Html.BeginForm("Add","Job")) {
  @foreach (var parameter in Model.Parameters)
  {
    @Html.Action("AddParameter","Job", parameter)
  }
 </fieldset>
}
</code>```

AddParameter View

```<code>@model Models.Parameter

<div class="editor-label">
    <label for="@Model.Name">@Model.Name</label>
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Value)
</div>
</code>```

when this get's posted back to the below controller the list is not populated. I think i'm probably going about it in completely the wrong way but no idea how to really implement it. It seems the "dynamic" parameter concept is the thing really throwing me. Will this approach work and i've just got some things wrong? or do i need to look at another way of doing it?

Controller

```<code>[HttpPost]
public ActionResult Add(Job model)
{
    //Do Something
    return PartialView();
}
</code>```

答:
Your problem is related to returning a List from the view... check this post by Phil Haack:

Model Binding To A List

Here you can see I ran into the same problem. The solution proposed guided me in the right direction but it wasn't the one I used, I used Phil's post.

My Post

Hope this helps...

EDIT: To clarify, what you need to do is change your AddParameter View into an EditorTemplate and use it as instructed in the above post by Phil.

Body:
Need a hand/guide of creating a view that handles a list of parameters which we get the name of during run time, currently during the postback it just won't return anything, using the MVC html helpers.

My Models

public class Parameter {
  public string Name {get; set;}
  public string Value {get; set;}
}

public class Job {
  public List<Parameter> parameters {get; set;}
}

My Views

Add View

@model Models.Job
@using (Html.BeginForm("Add","Job")) {
  @foreach (var parameter in Model.Parameters)
  {
    @Html.Action("AddParameter","Job", parameter)
  }
 </fieldset>
}

AddParameter View

@model Models.Parameter

    @Model.Name

    @Html.EditorFor(model => model.Value)

when this get's posted back to the below controller the list is not populated. I think i'm probably going about it in completely the wrong way but no idea how to really implement it. It seems the "dynamic" parameter concept is the thing really throwing me. Will this approach work and i've just got some things wrong? or do i need to look at another way of doing it?

Controller

[HttpPost]
public ActionResult Add(Job model)
{
    //Do Something
    return PartialView();
}


问:
React won't draw anything in the canvas in useEffect
I building a react website with matter.js. I am using the useEffect hook to render stuff to the canvas with matter.js (I found most of this code here). However, when I try to draw anything else to the canvas, nothing appears. Everything matter.js-related works.

const scene = useRef()
const isDragging = useRef(false)
const engine = useRef(Engine.create())

useEffect(() => {
  const cw = 1100;
  const ch = 700;
  const render = Render.create({
    canvas: scene.current,
    engine: engine.current,
    options: {
      width: cw,
      height: ch,
      wireframes: false,
      background: 'transparent'
    }
  })

  console.log("gravity " + engine.current.gravity.y + "x : " + engine.current.gravity.x)

  let mouse = Mouse.create(render.canvas);
  let mouseConstraint = MouseConstraint.create(engine.current, {
    mouse: mouse,
    constraint: {
      render: {
        visible: false
      }
    }
  })
  render.mouse = mouse;

  World.add(engine.current.world, [
    Bodies.rectangle(cw / 2, 0, cw, 20, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(cw / 2, ch, cw, 20, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(0, ch / 2, 20, ch, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(cw, ch / 2, 20, ch, {
      isStatic: true,
      density: 1
    }),

    mouseConstraint,
  ])

  Runner.run(engine.current)
  Render.run(render)

  Events.on(mouseConstraint, "mousedown", function(event) {
    handleSelections(mouseConstraint.body)
  })
  Events.on(mouseConstraint, "startdrag", function(event) {
    isDragging.current = true
  })
  Events.on(mouseConstraint, "enddrag", function() {
    isDragging.current = false
  })
  Events.on(engine.current, 'afterUpdate', function() {
    countTen.current = countTen.current + 1;

    if (countTen.current == 10) {
      countTen.current = 0;

      if (selectedObjectRef.current != null) {

        setGraphingPos(selectedObjectRef.current.velocity.y * -1);

        setTicks(ticks + 1)
      }
    }
  })

  // ******************* This part doesn't work **************************
  scene.current.getContext('2d').beginPath();
  scene.current.getContext('2d').arc(100, 100, 20, 0, 2 * Math.PI, false);
  scene.current.getContext('2d').fillStyle = 'red';
  scene.current.getContext('2d').fill();
  // **********************************************************************
  return () => {
    Render.stop(render)
    World.clear(engine.current.world)
    Engine.clear(engine.current)
    render.canvas.remove()
    render.canvas = null
    render.context = null
    render.textures = {}
  }
}, [])
```
<pre class="lang-html prettyprint-override"><code><canvas ref={scene} onClick={ handleMouseDown} className='main-canvas'></canvas>
</code>```

Any kind of help is much appreciated!

答:
Currently, you're drawing one time, up front, on the same canvas that MJS wipes per frame. So, you draw your circle, then MJS wipes the canvas immediately when it renders its first frame. You never attempt to draw again as the engine and renderer run onward.

I see a few solutions (at least!). Which is most appropriate depends on your specific use case.

Draw on the canvas on each frame inside the afterRender callback for the render object. This is the simplest and most direct solution from where you are now and I provide an example below.

Add a second transparent canvas on top of the one you're providing to MJS. This is done with absolute positioning. Now you can do whatever you want in this overlay without interference from MJS.

Run MJS headlessly, which gives you maximum control, as the MJS built-in renderer is mostly intended for protoyping (it's a physics engine, not a graphics engine). Once you're headless, you can render whatever you want, whenever you want, however you want. I have many demos of headless rendering in my other answers, both to the plain DOM and with React and p5.js.

As an aside, this doesn't appear related to React or useEffect in any way; the same problem would arise even if you were injecting a plain canvas in vanilla JS.

Also, keep in mind that whatever you draw is totally unrelated to MJS other than the fact that it happens to be on the same canvas. Don't expect physics to work on it, unless you're using coordinates from a body MJS knows about.

Although you haven't provided a full component, here's a minimal proof-of-concept of the afterRender approach mentioned above:

const {useEffect, useRef} = React;
const {Bodies, Engine, Events, Render, Runner, Composite} = Matter;

const Scene = () => {
  const canvasRef = useRef();

  useEffect(() => {
    const cw = 200;
    const ch = 200;
    const engine = Engine.create();
    const ctx = canvasRef.current.getContext("2d");
    const render = Render.create({
      canvas: canvasRef.current,
      engine,
      options: {
        width: cw,
        height: ch,
        wireframes: false,
        background: "transparent",
      }
    });
    const handleAfterRender = () => {
      const x = Math.cos(Date.now() / 300) * 80 + 100;
      const y = Math.sin(Date.now() / 299) * 80 + 100;
      ctx.beginPath();
      ctx.arc(x, y, 20, 0, 2 * Math.PI);
      ctx.fillStyle = "red";
      ctx.fill();
    };
    Events.on(render, "afterRender", handleAfterRender);
    Composite.add(engine.world, [
      Bodies.rectangle(cw / 2, 0, cw, 20, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(cw / 2, ch, cw, 20, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(0, ch / 2, 20, ch, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(cw, ch / 2, 20, ch, {
        isStatic: true,
        density: 1,
      }),
    ]);
    Runner.run(engine);
    Render.run(render);

    return () => {
      Events.off("afterRender", handleAfterRender);
      Render.stop(render);
      Composite.clear(engine.world);
      Engine.clear(engine);
      render.canvas.remove();
      render.canvas = null;
      render.context = null;
      render.textures = {};
    };
  }, []);
  return <canvas ref={canvasRef}></canvas>;
};

const root = document.querySelector("#app");
ReactDOM.createRoot(root).render(<Scene />);```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<div id="app"></div></code>```

Body:
I building a react website with matter.js. I am using the useEffect hook to render stuff to the canvas with matter.js (I found most of this code here). However, when I try to draw anything else to the canvas, nothing appears. Everything matter.js-related works.

const scene = useRef()
const isDragging = useRef(false)
const engine = useRef(Engine.create())

useEffect(() => {
  const cw = 1100;
  const ch = 700;
  const render = Render.create({
    canvas: scene.current,
    engine: engine.current,
    options: {
      width: cw,
      height: ch,
      wireframes: false,
      background: 'transparent'
    }
  })

  console.log("gravity " + engine.current.gravity.y + "x : " + engine.current.gravity.x)

  let mouse = Mouse.create(render.canvas);
  let mouseConstraint = MouseConstraint.create(engine.current, {
    mouse: mouse,
    constraint: {
      render: {
        visible: false
      }
    }
  })
  render.mouse = mouse;

  World.add(engine.current.world, [
    Bodies.rectangle(cw / 2, 0, cw, 20, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(cw / 2, ch, cw, 20, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(0, ch / 2, 20, ch, {
      isStatic: true,
      density: 1
    }),
    Bodies.rectangle(cw, ch / 2, 20, ch, {
      isStatic: true,
      density: 1
    }),

    mouseConstraint,
  ])

  Runner.run(engine.current)
  Render.run(render)

  Events.on(mouseConstraint, "mousedown", function(event) {
    handleSelections(mouseConstraint.body)
  })
  Events.on(mouseConstraint, "startdrag", function(event) {
    isDragging.current = true
  })
  Events.on(mouseConstraint, "enddrag", function() {
    isDragging.current = false
  })
  Events.on(engine.current, 'afterUpdate', function() {
    countTen.current = countTen.current + 1;

    if (countTen.current == 10) {
      countTen.current = 0;

      if (selectedObjectRef.current != null) {

        setGraphingPos(selectedObjectRef.current.velocity.y * -1);

        setTicks(ticks + 1)
      }
    }
  })

  // ******************* This part doesn't work **************************
  scene.current.getContext('2d').beginPath();
  scene.current.getContext('2d').arc(100, 100, 20, 0, 2 * Math.PI, false);
  scene.current.getContext('2d').fillStyle = 'red';
  scene.current.getContext('2d').fill();
  // **********************************************************************
  return () => {
    Render.stop(render)
    World.clear(engine.current.world)
    Engine.clear(engine.current)
    render.canvas.remove()
    render.canvas = null
    render.context = null
    render.textures = {}
  }
}, [])

<canvas ref={scene} onClick={ handleMouseDown} className='main-canvas'></canvas>

Any kind of help is much appreciated!

Body:
Currently, you're drawing one time, up front, on the same canvas that MJS wipes per frame. So, you draw your circle, then MJS wipes the canvas immediately when it renders its first frame. You never attempt to draw again as the engine and renderer run onward.

I see a few solutions (at least!). Which is most appropriate depends on your specific use case.

Draw on the canvas on each frame inside the afterRender callback for the render object. This is the simplest and most direct solution from where you are now and I provide an example below.

Add a second transparent canvas on top of the one you're providing to MJS. This is done with absolute positioning. Now you can do whatever you want in this overlay without interference from MJS.

Run MJS headlessly, which gives you maximum control, as the MJS built-in renderer is mostly intended for protoyping (it's a physics engine, not a graphics engine). Once you're headless, you can render whatever you want, whenever you want, however you want. I have many demos of headless rendering in my other answers, both to the plain DOM and with React and p5.js.

As an aside, this doesn't appear related to React or useEffect in any way; the same problem would arise even if you were injecting a plain canvas in vanilla JS.

Also, keep in mind that whatever you draw is totally unrelated to MJS other than the fact that it happens to be on the same canvas. Don't expect physics to work on it, unless you're using coordinates from a body MJS knows about.

Although you haven't provided a full component, here's a minimal proof-of-concept of the afterRender approach mentioned above:

const {useEffect, useRef} = React;
const {Bodies, Engine, Events, Render, Runner, Composite} = Matter;

const Scene = () => {
  const canvasRef = useRef();

  useEffect(() => {
    const cw = 200;
    const ch = 200;
    const engine = Engine.create();
    const ctx = canvasRef.current.getContext("2d");
    const render = Render.create({
      canvas: canvasRef.current,
      engine,
      options: {
        width: cw,
        height: ch,
        wireframes: false,
        background: "transparent",
      }
    });
    const handleAfterRender = () => {
      const x = Math.cos(Date.now() / 300) * 80 + 100;
      const y = Math.sin(Date.now() / 299) * 80 + 100;
      ctx.beginPath();
      ctx.arc(x, y, 20, 0, 2 * Math.PI);
      ctx.fillStyle = "red";
      ctx.fill();
    };
    Events.on(render, "afterRender", handleAfterRender);
    Composite.add(engine.world, [
      Bodies.rectangle(cw / 2, 0, cw, 20, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(cw / 2, ch, cw, 20, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(0, ch / 2, 20, ch, {
        isStatic: true,
        density: 1,
      }),
      Bodies.rectangle(cw, ch / 2, 20, ch, {
        isStatic: true,
        density: 1,
      }),
    ]);
    Runner.run(engine);
    Render.run(render);

    return () => {
      Events.off("afterRender", handleAfterRender);
      Render.stop(render);
      Composite.clear(engine.world);
      Engine.clear(engine);
      render.canvas.remove();
      render.canvas = null;
      render.context = null;
      render.textures = {};
    };
  }, []);
  return <canvas ref={canvasRef}></canvas>;
};

const root = document.querySelector("#app");
ReactDOM.createRoot(root).render(<Scene />);

<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.min.js"></script>
<div id="app"></div>


问:
Terraform Apply always modifies a Security Group in place
my Terraform project always seems to modify this aws_security_group.jacobs_rds_security_group_tf resource in-place when I run terraform apply.  Everything still works it just makes debugging weird when I always have an extra resource getting modified even though nothing about it is changing.

I have 2 security groups; 1 is for my RDS DB which whitelists incoming traffic, and the other is for tasks and it attaches to my ECS & Lambda tasks so they can access this RDS DB.  The Task Security Group is whitelisted in the RDS Security Group.

The RDS Security group (aws_security_group.jacobs_rds_security_group_tf) is the one that is always getting modified in-place.  Below is the code.

```<code>resource "aws_vpc" "jacobs_vpc_tf" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

}

resource "aws_security_group" "jacobs_task_security_group_tf"{
    name = "jacobs_security_group for tasks"
    description = "Connect Tasks to RDS"
    vpc_id = aws_vpc.jacobs_vpc_tf.id

    ingress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

    egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}

resource "aws_security_group" "jacobs_rds_security_group_tf" {
  name        = "jacobs_security_group for rds"
  description = "Allow Jacobs Traffic to RDS"
  vpc_id      = aws_vpc.jacobs_vpc_tf.id

  ingress {
    description      = "Custom IP Addresses"
    from_port        = 5432
    to_port          = 5432
    protocol         = "tcp"
    cidr_blocks      = var.jacobs_cidr_block

  }

  ingress {
    description      = "Other Security Groups"
    from_port        = -1
    to_port          = -1
    protocol         = "all"
    security_groups  = [aws_security_group.jacobs_task_security_group_tf.id] # this should be changed to vpc_security_group_ids ?
  }

  # outbound
  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

}

</code>```

I research this problem about once a month and screw around with the Terraform to try & fix it and have had no success.  The github issues I come across don't seem to apply to my setup, but maybe I'm missing something obvious?  Any help would be appreciated!

答:
I think your problem is that you have this ingress rule:

```<code>ingress {
    description      = "Other Security Groups"
    from_port        = -1
    to_port          = -1
    protocol         = "all"
    security_groups  = [aws_security_group.jacobs_task_security_group_tf.id]
  }
</code>```

You have the from_port and to_port set to -1. You should set them to 0. From the docs:

If you select a protocol of -1 (semantically equivalent to all, which is not a valid value here), you must specify a from_port and to_port equal to 0.

What is happening in this case is that Terraform (or the AWS API used by Terraform) will set them to 0, without erroring out. Since there was a change after the apply, Terraform will try will detect it when you do a plan again.

Moreover, I think the docs are not accurate here, setting all to protocol is allowed here (at least with the Terraform version I've tried, v1.0.11, AWS provider version 3.70.0).

Body:
my Terraform project always seems to modify this aws_security_group.jacobs_rds_security_group_tf resource in-place when I run terraform apply.  Everything still works it just makes debugging weird when I always have an extra resource getting modified even though nothing about it is changing.

I have 2 security groups; 1 is for my RDS DB which whitelists incoming traffic, and the other is for tasks and it attaches to my ECS & Lambda tasks so they can access this RDS DB.  The Task Security Group is whitelisted in the RDS Security Group.

The RDS Security group (aws_security_group.jacobs_rds_security_group_tf) is the one that is always getting modified in-place.  Below is the code.

resource "aws_vpc" "jacobs_vpc_tf" {
  cidr_block = "10.0.0.0/16"
  enable_dns_hostnames = true

}

resource "aws_security_group" "jacobs_task_security_group_tf"{
    name = "jacobs_security_group for tasks"
    description = "Connect Tasks to RDS"
    vpc_id = aws_vpc.jacobs_vpc_tf.id

    ingress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

    egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }
}

resource "aws_security_group" "jacobs_rds_security_group_tf" {
  name        = "jacobs_security_group for rds"
  description = "Allow Jacobs Traffic to RDS"
  vpc_id      = aws_vpc.jacobs_vpc_tf.id

  ingress {
    description      = "Custom IP Addresses"
    from_port        = 5432
    to_port          = 5432
    protocol         = "tcp"
    cidr_blocks      = var.jacobs_cidr_block

  }

  ingress {
    description      = "Other Security Groups"
    from_port        = -1
    to_port          = -1
    protocol         = "all"
    security_groups  = [aws_security_group.jacobs_task_security_group_tf.id] # this should be changed to vpc_security_group_ids ?
  }

  # outbound
  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

}

I research this problem about once a month and screw around with the Terraform to try & fix it and have had no success.  The github issues I come across don't seem to apply to my setup, but maybe I'm missing something obvious?  Any help would be appreciated!

Body:
I think your problem is that you have this ingress rule:

ingress {
    description      = "Other Security Groups"
    from_port        = -1
    to_port          = -1
    protocol         = "all"
    security_groups  = [aws_security_group.jacobs_task_security_group_tf.id]
  }

You have the from_port and to_port set to -1. You should set them to 0. From the docs:

If you select a protocol of -1 (semantically equivalent to all, which is not a valid value here), you must specify a from_port and to_port equal to 0.

What is happening in this case is that Terraform (or the AWS API used by Terraform) will set them to 0, without erroring out. Since there was a change after the apply, Terraform will try will detect it when you do a plan again.

Moreover, I think the docs are not accurate here, setting all to protocol is allowed here (at least with the Terraform version I've tried, v1.0.11, AWS provider version 3.70.0).


问:
Swift UI Scroll View: Set frame for drag indicator
I have following problem. I want to create a vertical ScrollView with many rows. At the bottom of the view I have an info bar which appears over the scroll view because I put all the items in a ZStack. Here is my code and what it produces:

struct ProblemView: View {

    var body: some View {
        ZStack {
            ScrollView(.vertical, showsIndicators: true) {

                VStack {
                    ForEach(0..<100, id:\.self) {i in
                        HStack {
                            Text("Text \(i)")
                                .foregroundColor(.red)
                            Spacer()
                            Image(systemName: "plus")
                                .foregroundColor(.blue)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding()
                        Divider()

                    }
                }
            }

            VStack {
                Spacer()
                HStack {
                    Text("Some Info here")
                    Image(systemName: "info.circle")
                        .foregroundColor(.blue)
                }
                .padding()
                .frame(maxWidth: .infinity)
                .ignoresSafeArea()
                .background(.ultraThinMaterial)

            }

        }
    }

}

struct ProblemView_Previews: PreviewProvider {
    static var previews: some View {
        ProblemView()
    }
}
```

As you can see the drag indicator is hidden behind the info frame. Also the last item can't be seen because it is also behind the other frame. What

I want is that the drag indicator stops at this info frame. Why am I using a ZStack and not just a VStack? I want that this opacity effect behind the info frame, you get when you scroll.

答:
A edit on my preview post has been added and therefore I cannot edit it... I am just gonna post the answer as an other one then.

This is the code that fixes your problem:

```<code>import SwiftUI

struct ProblemView: View {
  var body: some View {
    ScrollView {

        VStack {
            ForEach(0..<100, id:\.self) {i in
                HStack {
                    Text("Text \(i)")
                      .foregroundColor(.red)
                    Spacer()
                    Image(systemName: "plus")
                      .foregroundColor(.blue)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding()
                Divider()
            }
      }
      .frame(maxWidth: .infinity)
    }
    .safeAreaInset(edge: .bottom) { //
        VStack {

            HStack {
                Text("Some Info here")
                Image(systemName: "info.circle")
                    .foregroundColor(.blue)
            }
            .padding()
            .frame(maxWidth: .infinity)
            .ignoresSafeArea()
            .background(.ultraThinMaterial)

        }
  }
}
}

struct ProblemView_Previews: PreviewProvider {
    static var previews: some View {
        ProblemView()
    }
}
</code>```

Body:
I have following problem. I want to create a vertical ScrollView with many rows. At the bottom of the view I have an info bar which appears over the scroll view because I put all the items in a ZStack. Here is my code and what it produces:

struct ProblemView: View {

    var body: some View {
        ZStack {
            ScrollView(.vertical, showsIndicators: true) {

                VStack {
                    ForEach(0..<100, id:\.self) {i in
                        HStack {
                            Text("Text \(i)")
                                .foregroundColor(.red)
                            Spacer()
                            Image(systemName: "plus")
                                .foregroundColor(.blue)
                        }
                        .frame(maxWidth: .infinity, alignment: .leading)
                        .padding()
                        Divider()

                    }
                }
            }

            VStack {
                Spacer()
                HStack {
                    Text("Some Info here")
                    Image(systemName: "info.circle")
                        .foregroundColor(.blue)
                }
                .padding()
                .frame(maxWidth: .infinity)
                .ignoresSafeArea()
                .background(.ultraThinMaterial)

            }

        }
    }

}

struct ProblemView_Previews: PreviewProvider {
    static var previews: some View {
        ProblemView()
    }
}

As you can see the drag indicator is hidden behind the info frame. Also the last item can't be seen because it is also behind the other frame. What

I want is that the drag indicator stops at this info frame. Why am I using a ZStack and not just a VStack? I want that this opacity effect behind the info frame, you get when you scroll.

Body:
A edit on my preview post has been added and therefore I cannot edit it... I am just gonna post the answer as an other one then.

This is the code that fixes your problem:

import SwiftUI

struct ProblemView: View {
  var body: some View {
    ScrollView {

        VStack {
            ForEach(0..<100, id:\.self) {i in
                HStack {
                    Text("Text \(i)")
                      .foregroundColor(.red)
                    Spacer()
                    Image(systemName: "plus")
                      .foregroundColor(.blue)
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .padding()
                Divider()
            }
      }
      .frame(maxWidth: .infinity)
    }
    .safeAreaInset(edge: .bottom) { //
        VStack {

            HStack {
                Text("Some Info here")
                Image(systemName: "info.circle")
                    .foregroundColor(.blue)
            }
            .padding()
            .frame(maxWidth: .infinity)
            .ignoresSafeArea()
            .background(.ultraThinMaterial)

        }
  }
}
}

struct ProblemView_Previews: PreviewProvider {
    static var previews: some View {
        ProblemView()
    }
}