问:
SwiftUI, Core Data, ScrollViewReader - [error] precondition failure: invalid graph update (access from multiple threads?)
I'm trying to make a list of Core Data items in SwiftUI where adding new item will also trigger scroll to last item.

Here is a code I have. It's based on sample Core Data app in Xcode. One Entity: Item with one attribute: timestamp.

```<code>import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            ScrollViewReader { proxy in
                ScrollView {
                    ForEach(items, id: \.self) { item in
                        Text("Some item")
                            .padding()
                            .id(item.objectID)
                    }
                    .onDelete(perform: deleteItems)
                }
                .onChange(of: items.count) { _ in
//                  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                        withAnimation {
                            proxy.scrollTo(items.last?.objectID)
                        }
//                  }
                }
                .toolbar {
                    ToolbarItem {
                        Button(action: addItem) {
                            Label("Add Item", systemImage: "plus")
                        }
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}
</code>```

It works, but I'm getting errors like this in Xcode:

2022-02-06 16:28:47.280984+0700 scroll[901:2894134] [error]
precondition failure: invalid graph update (access from multiple
threads?)

How to fix this? My guess is that it's something to do with concurrency. When new item is created it gets new id. Number of item changes. Core Data saves data. UI scrolls with animation. But maybe when scroll is triggered, swift is still not sure which item is last on the list?

So, things I've tried:

If you uncomment

```<code>DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
</code>```

And closing bracket as well - I am not getting an error when I'm adding one item at a time. But if I tap + few times, I'm getting errors again.

Another surprising thing is that if I change ScrollView to List, I am not getting errors at all. Even without DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

答:
It appears that the ScrollView wants a VStack around the ForEach AND that .scrollTo() does not like an optional AND you need the DispatchQueue.main.asyncAfter(deadline:) with an actual delay. I found some references to fixing it for the VStack, but no explanation as to why it works. However, I think these are independent problems that cause the same error, so all fixes had to be made.

```<code>struct ContentView: View {

    // Nothing changed here

    var body: some View {
        NavigationView {
            ScrollViewReader { proxy in
                ScrollView {
                    VStack {
                        ForEach(items, id: \.self) { item in
                            Text("Some item")
                                .padding()
                                .id(item.objectID)
                        }
                        .onDelete(perform: deleteItems)
                    }
                }
                .onChange(of: items.count) { _ in
                    if let last = items.last {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            withAnimation {
                                proxy.scrollTo(last.objectID)
                            }
                        }
                    }
                }

    // Nothing changed here

}
</code>```

Body:
I'm trying to make a list of Core Data items in SwiftUI where adding new item will also trigger scroll to last item.

Here is a code I have. It's based on sample Core Data app in Xcode. One Entity: Item with one attribute: timestamp.

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            ScrollViewReader { proxy in
                ScrollView {
                    ForEach(items, id: \.self) { item in
                        Text("Some item")
                            .padding()
                            .id(item.objectID)
                    }
                    .onDelete(perform: deleteItems)
                }
                .onChange(of: items.count) { _ in
//                  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                        withAnimation {
                            proxy.scrollTo(items.last?.objectID)
                        }
//                  }
                }
                .toolbar {
                    ToolbarItem {
                        Button(action: addItem) {
                            Label("Add Item", systemImage: "plus")
                        }
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

It works, but I'm getting errors like this in Xcode:

2022-02-06 16:28:47.280984+0700 scroll[901:2894134] [error]
precondition failure: invalid graph update (access from multiple
threads?)

How to fix this? My guess is that it's something to do with concurrency. When new item is created it gets new id. Number of item changes. Core Data saves data. UI scrolls with animation. But maybe when scroll is triggered, swift is still not sure which item is last on the list?

So, things I've tried:

If you uncomment

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

And closing bracket as well - I am not getting an error when I'm adding one item at a time. But if I tap + few times, I'm getting errors again.

Another surprising thing is that if I change ScrollView to List, I am not getting errors at all. Even without DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {

Body:
It appears that the ScrollView wants a VStack around the ForEach AND that .scrollTo() does not like an optional AND you need the DispatchQueue.main.asyncAfter(deadline:) with an actual delay. I found some references to fixing it for the VStack, but no explanation as to why it works. However, I think these are independent problems that cause the same error, so all fixes had to be made.

struct ContentView: View {

    // Nothing changed here

    var body: some View {
        NavigationView {
            ScrollViewReader { proxy in
                ScrollView {
                    VStack {
                        ForEach(items, id: \.self) { item in
                            Text("Some item")
                                .padding()
                                .id(item.objectID)
                        }
                        .onDelete(perform: deleteItems)
                    }
                }
                .onChange(of: items.count) { _ in
                    if let last = items.last {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            withAnimation {
                                proxy.scrollTo(last.objectID)
                            }
                        }
                    }
                }

    // Nothing changed here

}


来源: stackexchange

问:
Tap to open File
In my app I have links for videos, now when you click on the link IE launches and asks you "Tap to open the File"

I was hoping to over come that, any suggestions?

I am using a simple HyperlinkButton that has an image as its template,

答:
Instead of using the HyperlinkButton's NavigateUri property, you could play the video inside a MediaElement on a separate page.

First, add a new page to your project (MoviePlayer.xaml) and put a single MediaElement in it. Handle the MediaElement.Loaded event in the code behind as well as wire up the OnNavigatedTo and OnNavigatingFrom events:

```<code>protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    var qs = NavigationContext.QueryString["url"];
    MyMovie.Source = new Uri(qs, UriKind.Absolute);
}

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
    MyMovie.Stop();
    base.OnNavigatingFrom(e);
}

private void MyMovie_Loaded(object sender, RoutedEventArgs e)
{
    MyMovie.Position = new TimeSpan(0);
    MyMovie.Play();
}
</code>```

Then in your main page, change the HyperlinkButton to handle the Click event instead of setting the NavigateUri property, and run something like this:

```<code>private void HyperlinkButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    var button = sender as HyperlinkButton;
    var video = button.DataContext as VideoWrapperClass; // name, url, playing time, etc.
    NavigationService.Navigate(new Uri("/MoviePlayer.xaml?url=" + video.Url, UriKind.Relative));
}
</code>```

That's all there is too it!  With this approach, you could also customize the playback experience if you wanted to, or run some custom animations such as bumpers or advertisement overlays.

If you'd rather see an MVVM-type solution, just ping me on Twitter at @chriskoenig and I'll shoot you over something.

/chris

ContentLicense: CC BY-SA 3.0

Title: Tap to open File

Body:
Instead of using the HyperlinkButton's NavigateUri property, you could play the video inside a MediaElement on a separate page.

First, add a new page to your project (MoviePlayer.xaml) and put a single MediaElement in it. Handle the MediaElement.Loaded event in the code behind as well as wire up the OnNavigatedTo and OnNavigatingFrom events:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    var qs = NavigationContext.QueryString["url"];
    MyMovie.Source = new Uri(qs, UriKind.Absolute);
}

protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
    MyMovie.Stop();
    base.OnNavigatingFrom(e);
}

private void MyMovie_Loaded(object sender, RoutedEventArgs e)
{
    MyMovie.Position = new TimeSpan(0);
    MyMovie.Play();
}

Then in your main page, change the HyperlinkButton to handle the Click event instead of setting the NavigateUri property, and run something like this:

private void HyperlinkButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    var button = sender as HyperlinkButton;
    var video = button.DataContext as VideoWrapperClass; // name, url, playing time, etc.
    NavigationService.Navigate(new Uri("/MoviePlayer.xaml?url=" + video.Url, UriKind.Relative));
}

That's all there is too it!  With this approach, you could also customize the playback experience if you wanted to, or run some custom animations such as bumpers or advertisement overlays.

If you'd rather see an MVVM-type solution, just ping me on Twitter at @chriskoenig and I'll shoot you over something.

/chris


问:
Determining worst-case time-complexity of this function?
I'm currently studying sets from Richard Hammack's 'Book of Proof' and I was trying to implement a set to a power (more specifically, the cartesian power of a set). An example of this is as follows:

Suppose I have set A = {0, 1}, then

A2 = {0, 1} x {0, 1} = {(0, 0), (0, 1), (1, 0), (1, 1)}

I successfully implemented a general function that could raise a set to any power I specified. The code is as follows:

```<code>def add_to_tuple(tup, a):
    tup = list(tup)
    tup.append(a)
    return tuple(tup)

def multiply(A, B):
    return_set = []
    for a in A:
        for b in B:
            if type(a) is tuple and type(b) is tuple:
                return_set.append(a + b)
            elif type(a) is not tuple and type(b) is tuple:
                return_set.append(add_to_tuple(b, a))
            elif type(a) is tuple and type(b) is not tuple:
                return_set.append(add_to_tuple(a, b))
            else:
                return_set.append((a, b))
    return return_set

def set_to_power(finite_set, power):
    if power == 1:
        return finite_set
    else:
        return multiply(finite_set, set_to_power(finite_set, power - 1))

a = [0, 1]
print(set_to_power(a, 2))
</code>```

The following output is:[(0, 0), (0, 1), (1, 0), (1, 1)]

I'm trying to figure out the time complexity of set_to_power and I'm not sure whether it's n2 or not.

答:
First let's look at multiply:
You've got 2 nested for loops with no breaks or returns, so whatever is in them will be executed len(A) * len(B) times. add_to_tuple depends on the size of a tuple; I'll get to that later, for now let's assume base case of power = 2 so add_to_tuple does not happen. In that case they are constant, so everything apart from for loops is in O(1) time. So yeah, your multiply will run in O(n^2) time for power 2.

Trouble starts when we get to set_to_power function - it has 2 parameters, both of which affect the complexity of the function. So it certainly won't be O(n^2) - we have to take into account the power variable somehow.
First of all, your add_to_tuple is O(i) (like 90% sure, although I'm not certain about inner workings of list() and tuple()) in terms of the power variable. So this already means each run of multiply will take O(i*(n^2)).
Then you are triggering that i times, each time with n times more elements in one of the sets.
I thiiiiink it's gonna be something like ~ O(i^2 * n * n^i) (i is roughly power-1, but I'm not sure how is that relevant in Big-O notation.)

ContentLicense: CC BY-SA 4.0

Body:
I'm currently studying sets from Richard Hammack's 'Book of Proof' and I was trying to implement a set to a power (more specifically, the cartesian power of a set). An example of this is as follows:

Suppose I have set A = {0, 1}, then

A2 = {0, 1} x {0, 1} = {(0, 0), (0, 1), (1, 0), (1, 1)}

I successfully implemented a general function that could raise a set to any power I specified. The code is as follows:

def add_to_tuple(tup, a):
    tup = list(tup)
    tup.append(a)
    return tuple(tup)

def multiply(A, B):
    return_set = []
    for a in A:
        for b in B:
            if type(a) is tuple and type(b) is tuple:
                return_set.append(a + b)
            elif type(a) is not tuple and type(b) is tuple:
                return_set.append(add_to_tuple(b, a))
            elif type(a) is tuple and type(b) is not tuple:
                return_set.append(add_to_tuple(a, b))
            else:
                return_set.append((a, b))
    return return_set

def set_to_power(finite_set, power):
    if power == 1:
        return finite_set
    else:
        return multiply(finite_set, set_to_power(finite_set, power - 1))

a = [0, 1]
print(set_to_power(a, 2))

The following output is:[(0, 0), (0, 1), (1, 0), (1, 1)]

I'm trying to figure out the time complexity of set_to_power and I'm not sure whether it's n2 or not.


问:
How can I remove a parameter from a subclass constructor in Java?
In my superclass, I have defined the parameters a, b, c and d. For its subclass, I want to remove d. Is there any way for me to do this?

abstract class Prescription {
    protected Medicine Medicine;
    protected Doctor doctor;
    protected int patientID, thing;
    public Resept(Medicine medicine, Doctor doctor, int patientID, int thing) {
        this.legemiddel = legemiddel;
        this.lege = utskrivendeLege;
        this.pasientID = pasientID;
        this.thing = thing;
```
<p>And in my subclass, I would like to create a constructor without the last parameter "thing"</p>
<pre class="lang-java prettyprint-override"><code>public class TypeBPrescription extends Prescription {
    public TypeBPresciption(Medicine medicine, Doctor doctor, int patientID){
        super(Medicine medicine, Doctor doctor, int patientID,)
    }
}
</code>```

Writing it like this gives me the error that the constructor in the subclass TypeBPrescription is undefined. I want the subclass to not have "thing", but I want my superclass to have it. Is there any way to do this?

答:
I would pass a default value to the super class.</p>
```<code>public TypeBPresciption(Medicine medicine, Doctor doctor, int patientID){
    super(medicine, doctor, patientID, 0)
}
</code>```

Body:
In my superclass, I have defined the parameters a, b, c and d. For its subclass, I want to remove d. Is there any way for me to do this?

abstract class Prescription {
    protected Medicine Medicine;
    protected Doctor doctor;
    protected int patientID, thing;
    public Resept(Medicine medicine, Doctor doctor, int patientID, int thing) {
        this.legemiddel = legemiddel;
        this.lege = utskrivendeLege;
        this.pasientID = pasientID;
        this.thing = thing;

And in my subclass, I would like to create a constructor without the last parameter "thing"

public class TypeBPrescription extends Prescription {
    public TypeBPresciption(Medicine medicine, Doctor doctor, int patientID){
        super(Medicine medicine, Doctor doctor, int patientID,)
    }
}

Writing it like this gives me the error that the constructor in the subclass TypeBPrescription is undefined. I want the subclass to not have "thing", but I want my superclass to have it. Is there any way to do this?

Body:
I would pass a default value to the super class.

public TypeBPresciption(Medicine medicine, Doctor doctor, int patientID){
    super(medicine, doctor, patientID, 0)
}


问:
How to set android layout height to x% of its parent height?
I would like to create this simple layout:

I wrote this:

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/purple_200">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.3"
        android:background="@color/black" />

</LinearLayout>
</code>```

But doing so I don't see any black view appearing. What am I missing?

答:
All you have to do is to add

```<code>android:weightSum="1"
</code>```

to your parent's layout, so

```<code><?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1"
    android:background="@color/purple_200">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.3"
        android:background="@color/black" />

</LinearLayout>
</code>```

I suppose you thought it's 1 by default, but it's not, you have to specify it, otherwise, it's calculated as the sum of the children's weights, so in this case, it was 0.3.

From the android:weightSum's definition:

Defines the maximum weight sum. If unspecified, the sum is computed by
adding the layout_weight of all of the children. This can be used for
instance to give a single child 50% of the total available space by
giving it a layout_weight of 0.5 and setting the weightSum to 1.0.

Body:
I would like to create this simple layout:

I wrote this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/purple_200">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.3"
        android:background="@color/black" />

</LinearLayout>

But doing so I don't see any black view appearing. What am I missing?

Body:
All you have to do is to add

android:weightSum="1"

to your parent's layout, so

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1"
    android:background="@color/purple_200">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.3"
        android:background="@color/black" />

</LinearLayout>

I suppose you thought it's 1 by default, but it's not, you have to specify it, otherwise, it's calculated as the sum of the children's weights, so in this case, it was 0.3.

From the android:weightSum's definition:

Defines the maximum weight sum. If unspecified, the sum is computed by
adding the layout_weight of all of the children. This can be used for
instance to give a single child 50% of the total available space by
giving it a layout_weight of 0.5 and setting the weightSum to 1.0.


问:
Website renders like desktop on mobile, only when first loaded or is refreshed
I have created a website that uses media queries and is responsive when tested from the Dev tools in browser. However it reverts back to its desktop-like state on reloading. If i click on a link that redirects me to another page, it is displays the second page perfectly as expected. Same for when i go "back". The homepage is now magically responsive.

[View the issue : ]https://reach-tech-interns-page1.vercel.app/

Upon opening on mobile, this link doesn't seem responsive. But click on testimonials and go back, and the homepage is now responsive. If I reload, the mobile site breaks again.

I used Next.js and Chakra UI.

[Github Code:] https://github.com/inferno080/Reach-Tech-Interns-Page

答:
The issue was with Chakra UI's useMediaQuery() hook. Writing a custom hook solved this issue</p>
```<code>
const useMediaQuery = (query) => {
  const [matches, setMatches] = useState(false);

  useEffect(() => {
    const media = window.matchMedia(query);
    if (media.matches !== matches) {
      setMatches(media.matches);
    }
    const listener = () => setMatches(media.matches);
    window.addEventListener("resize", listener);
    return () => window.removeEventListener("resize", listener);
  }, [matches, query]);

  return matches;
}

export default useMediaQuery;
</code>```

Body:
The issue was with Chakra UI's useMediaQuery() hook. Writing a custom hook solved this issue

const useMediaQuery = (query) => {
  const [matches, setMatches] = useState(false);

  useEffect(() => {
    const media = window.matchMedia(query);
    if (media.matches !== matches) {
      setMatches(media.matches);
    }
    const listener = () => setMatches(media.matches);
    window.addEventListener("resize", listener);
    return () => window.removeEventListener("resize", listener);
  }, [matches, query]);

  return matches;
}

export default useMediaQuery;


问:
How to use a new token to push to github?
In order to push something to github it looks like I need to create a new token (again...). But what that new token, how do I tell git to use a new token? What command do I have to use to use the new token?

答:
It seems that git does not provide a 'nice' way to update your token. But here is how you can do it:

You remove the old origin

```<code>git remote remove origin
</code>```

You add the new origin with the token integrated, i.e.

```<code>git remote add origin https://<token>@github.com/<username>/<reponame>.git
</code>```

so it looks like e.g.

```<code>git remote add origin https://ghp_hgv674bbdgdytewyeegegd@github.com/alex526/myrepo.git
</code>```

Hint:

Sometimes this procedure will not work.

Body:
It seems that git does not provide a 'nice' way to update your token. But here is how you can do it:

You remove the old origin

git remote remove origin

You add the new origin with the token integrated, i.e.

git remote add origin https://<token>@github.com/<username>/<reponame>.git

so it looks like e.g.

git remote add origin https://ghp_hgv674bbdgdytewyeegegd@github.com/alex526/myrepo.git

Hint:

Sometimes this procedure will not work.


问:
malloc convert memory for struct
What is the right way to malloc memory ? And what is the difference between them ?

```<code>void parse_cookies(const char *cookie, cookie_bank **my_cookie, int *cookies_num)
{
   *my_cookie = malloc(sizeof(cookie_bank) * 1);
   *my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);
   my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);
   ///
}
</code>```

I'm trying to malloc array of cookie_bank structs function.

答:
Your second example is the most correct. You don't need the *1 obviously.

```<code>*my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);
</code>```

Your first example is also correct, although some compilers/flags will cause a complaint about the implicit cast from void*:

```<code>*my_cookie = malloc(sizeof(cookie_bank) * 1);
</code>```

It you want to allocate more than one entry you'd generally use calloc() because it zeros the memory too:

```<code>*my_cookie = (cookie_bank*)calloc(sizeof(cookie_bank), 1);
</code>```

your third example is just wrong:

```<code>my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);
</code>```

This will overwrite the local my_cookie pointer, and the memory will be lost on function return.

Title: malloc convert memory for struct

Body:
What is the right way to malloc memory ? And what is the difference between them ?

void parse_cookies(const char *cookie, cookie_bank **my_cookie, int *cookies_num)
{
   *my_cookie = malloc(sizeof(cookie_bank) * 1);
   *my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);
   my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);
   ///
}

I'm trying to malloc array of cookie_bank structs function.

Body:
Your second example is the most correct. You don't need the *1 obviously.

*my_cookie = (cookie_bank *)malloc(sizeof(cookie_bank) * 1);

Your first example is also correct, although some compilers/flags will cause a complaint about the implicit cast from void*:

*my_cookie = malloc(sizeof(cookie_bank) * 1);

It you want to allocate more than one entry you'd generally use calloc() because it zeros the memory too:

*my_cookie = (cookie_bank*)calloc(sizeof(cookie_bank), 1);

your third example is just wrong:

my_cookie = (cookie_bank **)malloc(sizeof(cookie_bank) * 1);

This will overwrite the local my_cookie pointer, and the memory will be lost on function return.


问:
Converting a String to json in Swift. for sending in a websocket
I have a JS to send Json via websocket. as follows:

```<code>function senddata()
{
    var obj = {};
    var arrayOfRequests = [];
    arrayOfRequests.push({
        "id":22,
        "repeat":false,
    })
    obj.DataReq = arrayOfRequests;
    var stringToSend = JSON.stringify(obj);
    websocketConnection.send( stringToSend );
}
</code>```

This code works as expected, and the server sends back the requested info.

I am trying to do the same thing in swift.

```<code>   func send(text: String) {
        let message = text
        guard let json = try? JSONEncoder().encode(message),
            let jsonString = String(data: json, encoding: .utf8)
        else {
            return
        }
        webSocketTask?.send(.string(jsonString)){ error in
            if let error = error {
                print("Error sending message", error)
            }
        }
    }
send(text: "{“DataReq”:[{“id”:22,“repeat”:false}]}")
</code>```

With this the server does not send any response.

If Connect both of these examples to a websocket echo server

the JS code sends {"DataReq":[{"id":22,"repeat":false}]}

while the Swift codes send "{"DataReq":[{"id":9,"repeat":false}]}".

any help is appreciated.

答:
Encoding a JSON string to JSON is pointless. Remove the encoding part

```<code>func send(text: String) {
    webSocketTask?.send(.string(text)){ error in
        if let error = error {
            print("Error sending message", error)
        }
    }
}
</code>```

And in the send line the double quotes are invalid. Use this syntax

```<code>send(text: #"{"DataReq":[{"id":22,"repeat":false}]}"#)
</code>```

Body:
I have a JS to send Json via websocket. as follows:

function senddata()
{
    var obj = {};
    var arrayOfRequests = [];
    arrayOfRequests.push({
        "id":22,
        "repeat":false,
    })
    obj.DataReq = arrayOfRequests;
    var stringToSend = JSON.stringify(obj);
    websocketConnection.send( stringToSend );
}

This code works as expected, and the server sends back the requested info.

I am trying to do the same thing in swift.

   func send(text: String) {
        let message = text
        guard let json = try? JSONEncoder().encode(message),
            let jsonString = String(data: json, encoding: .utf8)
        else {
            return
        }
        webSocketTask?.send(.string(jsonString)){ error in
            if let error = error {
                print("Error sending message", error)
            }
        }
    }
send(text: "{“DataReq”:[{“id”:22,“repeat”:false}]}")

With this the server does not send any response.

If Connect both of these examples to a websocket echo server

the JS code sends {"DataReq":[{"id":22,"repeat":false}]}

while the Swift codes send "{"DataReq":[{"id":9,"repeat":false}]}".

any help is appreciated.

Body:
Encoding a JSON string to JSON is pointless. Remove the encoding part

func send(text: String) {
    webSocketTask?.send(.string(text)){ error in
        if let error = error {
            print("Error sending message", error)
        }
    }
}

And in the send line the double quotes are invalid. Use this syntax

send(text: #"{"DataReq":[{"id":22,"repeat":false}]}"#)


问:
'return' cannot transfer control out of a defer statement
```<code>func someone() -> String {
    defer {
        return "World"
    }
    return "Hello"
}

someone()
</code>```

for above snippet of code its throwing error "'return' cannot transfer control out of a defer statement" so what is the reason behind it?

答:
Returning more than one value is not allowed, regardless of whether you try to do that in a defer statement or not.

Whatever you do to mutate a return value in a defer statement, that's  not accessible via a return. It happens afterward.

func someone() -> String {
  var `return` = "Hello"

  defer {
    `return` += "World"
  }

  return `return`
}

someone() // Hello
```

Body:
func someone() -> String {
    defer {
        return "World"
    }
    return "Hello"
}

someone()

for above snippet of code its throwing error "'return' cannot transfer control out of a defer statement" so what is the reason behind it?


问:
Convert written out date (DD.MMMM.YYYY at hh:mm apm) string into date value
Unfortunately, the Google-Sheets sync extension saves the timestamp as a string. (Example: February 6, 2022 at 11:40 pm). Is there any way of automatically converting this automatically to an actual date? I tried the usual date conversion formulas but they dont work. Maybe a work-around?</p>

答:
if a timestamp is in cell A2, try this:

```<code>=1*SUBSTITUTE(A2,"at","")
</code>```

This just gets rid of the word "at" and then multiplying by 1 forces an attempt to convert it into a date value.  Then you can just do a regular Format>Number>Date and Time on that cell and it should show how you'd want.

Body:
if a timestamp is in cell A2, try this:

=1*SUBSTITUTE(A2,"at","")

This just gets rid of the word "at" and then multiplying by 1 forces an attempt to convert it into a date value.  Then you can just do a regular Format>Number>Date and Time on that cell and it should show how you'd want.


问:
Concatenation the string values in python
I am trying to concatenation the string values like below in the python

args = parser.parse_args()

regionCode = args.regionCode

azure_api_token = args.azure_api_token

computerName  = args.computerName

targetOu = 'OU=XXX,OU=$regionCode,OU=XXX,DC=XXX,DC=XX'

in the regioncode I am fetching the value from the build parameters I am trying to assign it in the target OU $regioncode but the value is not fetching or substituting

can someone please help me with the command how to substitute the variable value into the target OU

答:
To substitute a variable in a string in python you can do in many different ways.

Here you can do:

python 2:

```<code>targetOu = 'OU=XXX,OU={},OU=XXX,DC=XXX,DC=XX'.format(regionCode)
</code>```

python 3:

```<code>targetOu = f'OU=XXX,OU={regionCode},OU=XXX,DC=XXX,DC=XX'
</code>```

There are many other ways to do so. But this has been answered in so many different threads that I won't bother writing other solutions.

Body:
To substitute a variable in a string in python you can do in many different ways.

Here you can do:

python 2:

targetOu = 'OU=XXX,OU={},OU=XXX,DC=XXX,DC=XX'.format(regionCode)

python 3:

targetOu = f'OU=XXX,OU={regionCode},OU=XXX,DC=XXX,DC=XX'

There are many other ways to do so. But this has been answered in so many different threads that I won't bother writing other solutions.


问:
Merge people profiles based on email match
I have an existing directory (php with xml datasource) which contains people information such as this:

MainSource.xml

```<code><people>
    <person>
        <id></id>
        <last_name></last_name>
        <first_name></first_name>
        <email></email>
        <phone></phone>
    </person>
    ...
</people>
</code>```

I need to add a new node to MainSource.xml from NewSource.xml, matching on email address, from the new datasource which contains people info like this:

NewSource.xml

```<code><people>
    <person>
        <email></email>
        <website_url></website_url>
    </person>
    ...
</people>
</code>```

I have tried a number of variations, but I think my hangup is properly comparing the two documents. Logically, it feels like I need to be iterating, as opposed to foreach? Or two foreach, one for each source? Here's a sample of what I'm thinking. Please offer any clarity or insight which can nudge me along in the right direction.

```<code><?php
$doc1 = new DOMDocument();
$doc1->load('MainSource.xml');

$doc2 = new DOMDocument();
$doc2->load('NewSource.xml');

foreach ($doc1->person as $person) {
    if ($person->email === $doc2->person->email) {
        $node = $doc1->createElement("website_url", $valueFromDoc2);
        $newnode = $doc1->appendChild($node);
    }
}

$merged = $doc1->saveXML();
file_put_contents('MergedSource.xml', $merged)

?>
</code>```

答:
As mentioned by @waterloomatt, you need to use xpath to achieve that.

Assuming that MainSource.xml looks like this:

```<code><people>
    <person>
        <id>1</id>
        <last_name>smith</last_name>
        <first_name>john</first_name>
        <email>js@example.com</email>
        <phone>555-123-1234</phone>
    </person>
    <person>
        <id>2</id>
        <last_name>doe</last_name>
        <first_name>jane</first_name>
        <email>jd@anotherexample.com</email>
        <phone>666-234-2345</phone>
    </person>
</people>
</code>```

and NewSource.xml looks like this:

```<code><people>
 <person>
        <email>js@example.com</email>
        <website_url>js.example.com</website_url>
    </person>
    <person>
        <email>jd@anotherexample.com</email>
        <website_url>jd.anotherexample.com</website_url>
    </person>
   </people>
</code>```

you can try this:

```<code>$doc1->loadXML('MainSource.xml');
$xpath1 = new DOMXPath($doc1);
# find each person's email address
$sources = $xpath1->query('//person//email');

$doc2->loadXML('NewSource.xml');
$xpath2 = new DOMXPath($doc2);

foreach ($sources as $source) {
    #for each email address, get the parent and use that as the destination
    #of the new web address element
    $destination = $xpath1->query('..',$source);

    #in the other doc, search for each person whose email address matches
    #that of the first doc and get the relevant web address
    $exp2 = "//person[email[text()='{$source->nodeValue}']]//website_url";
    $target = $xpath2->query($exp2);

    #import the result of the search as a node into the first doc
    $node = $doc1->importNode($target[0], true);
    #finally, append the imported node in the right location of the first doc
    $destination[0]->appendChild($node);
};

echo $doc1->saveXml();
</code>```

Output:

```<code><people>
        <person>
            <id>1</id>
            <last_name>smith</last_name>
            <first_name>john</first_name>
            <email>js@example.com</email>
            <phone>555-123-1234</phone>
        <website_url>js.example.com</website_url></person>
        <person>
            <id>2</id>
            <last_name>doe</last_name>
            <first_name>jane</first_name>
            <email>jd@anotherexample.com</email>
            <phone>666-234-2345</phone>
        <website_url>jd.anotherexample.com</website_url></person>
    </people>
</code>```

Body:
I have an existing directory (php with xml datasource) which contains people information such as this:

MainSource.xml

<people>
    <person>
        <id></id>
        <last_name></last_name>
        <first_name></first_name>
        <email></email>
        <phone></phone>
    </person>
    ...
</people>

I need to add a new node to MainSource.xml from NewSource.xml, matching on email address, from the new datasource which contains people info like this:

NewSource.xml

<people>
    <person>
        <email></email>
        <website_url></website_url>
    </person>
    ...
</people>

I have tried a number of variations, but I think my hangup is properly comparing the two documents. Logically, it feels like I need to be iterating, as opposed to foreach? Or two foreach, one for each source? Here's a sample of what I'm thinking. Please offer any clarity or insight which can nudge me along in the right direction.

<?php
$doc1 = new DOMDocument();
$doc1->load('MainSource.xml');

$doc2 = new DOMDocument();
$doc2->load('NewSource.xml');

foreach ($doc1->person as $person) {
    if ($person->email === $doc2->person->email) {
        $node = $doc1->createElement("website_url", $valueFromDoc2);
        $newnode = $doc1->appendChild($node);
    }
}

$merged = $doc1->saveXML();
file_put_contents('MergedSource.xml', $merged)

?>

Body:
As mentioned by @waterloomatt, you need to use xpath to achieve that.

Assuming that MainSource.xml looks like this:

<people>
    <person>
        <id>1</id>
        <last_name>smith</last_name>
        <first_name>john</first_name>
        <email>js@example.com</email>
        <phone>555-123-1234</phone>
    </person>
    <person>
        <id>2</id>
        <last_name>doe</last_name>
        <first_name>jane</first_name>
        <email>jd@anotherexample.com</email>
        <phone>666-234-2345</phone>
    </person>
</people>

and NewSource.xml looks like this:

<people>
 <person>
        <email>js@example.com</email>
        <website_url>js.example.com</website_url>
    </person>
    <person>
        <email>jd@anotherexample.com</email>
        <website_url>jd.anotherexample.com</website_url>
    </person>
   </people>

you can try this:

$doc1->loadXML('MainSource.xml');
$xpath1 = new DOMXPath($doc1);
# find each person's email address
$sources = $xpath1->query('//person//email');

$doc2->loadXML('NewSource.xml');
$xpath2 = new DOMXPath($doc2);

foreach ($sources as $source) {
    #for each email address, get the parent and use that as the destination
    #of the new web address element
    $destination = $xpath1->query('..',$source);

    #in the other doc, search for each person whose email address matches
    #that of the first doc and get the relevant web address
    $exp2 = "//person[email[text()='{$source->nodeValue}']]//website_url";
    $target = $xpath2->query($exp2);

    #import the result of the search as a node into the first doc
    $node = $doc1->importNode($target[0], true);
    #finally, append the imported node in the right location of the first doc
    $destination[0]->appendChild($node);
};

echo $doc1->saveXml();

Output:

<people>
        <person>
            <id>1</id>
            <last_name>smith</last_name>
            <first_name>john</first_name>
            <email>js@example.com</email>
            <phone>555-123-1234</phone>
        <website_url>js.example.com</website_url></person>
        <person>
            <id>2</id>
            <last_name>doe</last_name>
            <first_name>jane</first_name>
            <email>jd@anotherexample.com</email>
            <phone>666-234-2345</phone>
        <website_url>jd.anotherexample.com</website_url></person>
    </people>


问:
file_put_contents() not working
I want to save the contents in the file in order.dat and now I'm using this PHP script:

```<code><?php
$a_str = array(
  "orderid"=>"175",
  "txnid"=>"RC456456456",
  "date"=>"54156456465",
  "amount"=>"109$"
);

$file = 'order.txt';
$contents = implode(PHP_EOL, $a_str);
//$contents = $orderid.'|'.$txnid.'|'.$date.'|'.$amount;
$contents .= PHP_EOL . PHP_EOL;
file_put_contents($file, $contents);
print("|$contents|");
?>
</code>```

How it is possible to save the data in order.dat file in this format?

```<code>175|RC456456456|54156456465|109$|
</code>```

答:
The second parameter should be the data: http://php.net/manual/en/function.file-put-contents.php

e.g.

```<code>$data = $orderid.'|'.$txnid.'|'.$date.'|'.$amount;
file_put_contents($file, $data, FILE_APPEND | LOCK_EX);
</code>```

It would probably be better to store the line data in an array and then implode it around the | character.

Title: file_put_contents() not working

Body:
I want to save the contents in the file in order.dat and now I'm using this PHP script:

<?php
$a_str = array(
  "orderid"=>"175",
  "txnid"=>"RC456456456",
  "date"=>"54156456465",
  "amount"=>"109$"
);

$file = 'order.txt';
$contents = implode(PHP_EOL, $a_str);
//$contents = $orderid.'|'.$txnid.'|'.$date.'|'.$amount;
$contents .= PHP_EOL . PHP_EOL;
file_put_contents($file, $contents);
print("|$contents|");
?>

How it is possible to save the data in order.dat file in this format?

175|RC456456456|54156456465|109$|

Body:
The second parameter should be the data: http://php.net/manual/en/function.file-put-contents.php

e.g.

$data = $orderid.'|'.$txnid.'|'.$date.'|'.$amount;
file_put_contents($file, $data, FILE_APPEND | LOCK_EX);

It would probably be better to store the line data in an array and then implode it around the | character.


问:
entity framework Core generate Wrong migrigation
i have model class like below

```<code>public class DIMAuthOffice
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ID { get; set; }
        public string Title { get; set; }
        [StringLength(50)]
        [Required]
        public string UserNameManager { get; set; }
        public int? ParentID { get; set; }
        [ForeignKey(nameof(ParentID))]
        public DIMAuthOffice OfficeParent { get; set; }
        public List<DIMAuthOffice> OfficeChilds { get; set; } = new List<DIMAuthOffice>();

        [ForeignKey(nameof(UserNameManager))]
        public DIMAuthUser UserManager { get; set; }
        public List<DIMAuthRole> DIMAuthRoles { get; set; } = new List<DIMAuthRole>();
        public List<DIMAuthRolePostOffice> DIMAuthRolePostOffices { get; set; } = new List<DIMAuthRolePostOffice>();

    }
</code>```

but when i execute

Add-Migration

the generated File is :

```<code>migrationBuilder.CreateTable(
                name: "DIMAuthOffices",
                columns: table => new
                {
                    ID = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: false),
                    UserNameManager = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
                    ParentID = table.Column<int>(type: "int", nullable: false),
                    UserManagerUserName = table.Column<string>(type: "nvarchar(50)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_DIMAuthOffices", x => x.ID);
                    table.ForeignKey(
                        name: "FK_DIMAuthOffices_DIMAuthOffices_ParentID",
                        column: x => x.ParentID,
                        principalTable: "DIMAuthOffices",
                        principalColumn: "ID");
                    table.ForeignKey(
                        name: "FK_DIMAuthOffices_DIMAuthUsers_UserManagerUserName",
                        column: x => x.UserManagerUserName,
                        principalTable: "DIMAuthUsers",
                        principalColumn: "UserName");
                });
</code>```

wrong line is :

ParentID = table.Column(type: "int", nullable: false),

the generated File is Wrong and property ParentID set to nullable:false but this should be true ...
why ???

答:
Doesn't repro for me on EF Core 6.  eg

```<code>public class DIMAuthOffice
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public string Title { get; set; }
    [StringLength(50)]
    [Required]
    public string UserNameManager { get; set; }
    public int? ParentID { get; set; }
    [ForeignKey(nameof(ParentID))]
    public DIMAuthOffice OfficeParent { get; set; }
    public List<DIMAuthOffice> OfficeChilds { get; set; } = new List<DIMAuthOffice>();

}
</code>```

creates an initial migration of:

```<code>    migrationBuilder.CreateTable(
        name: "DIMAuthOffice",
        columns: table => new
        {
            ID = table.Column<int>(type: "int", nullable: false)
                .Annotation("SqlServer:Identity", "1, 1"),
            Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
            UserNameManager = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
            ParentID = table.Column<int>(type: "int", nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_DIMAuthOffice", x => x.ID);
            table.ForeignKey(
                name: "FK_DIMAuthOffice_DIMAuthOffice_ParentID",
                column: x => x.ParentID,
                principalTable: "DIMAuthOffice",
                principalColumn: "ID");
        });
</code>```

Body:
i have model class like below

public class DIMAuthOffice
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ID { get; set; }
        public string Title { get; set; }
        [StringLength(50)]
        [Required]
        public string UserNameManager { get; set; }
        public int? ParentID { get; set; }
        [ForeignKey(nameof(ParentID))]
        public DIMAuthOffice OfficeParent { get; set; }
        public List<DIMAuthOffice> OfficeChilds { get; set; } = new List<DIMAuthOffice>();

        [ForeignKey(nameof(UserNameManager))]
        public DIMAuthUser UserManager { get; set; }
        public List<DIMAuthRole> DIMAuthRoles { get; set; } = new List<DIMAuthRole>();
        public List<DIMAuthRolePostOffice> DIMAuthRolePostOffices { get; set; } = new List<DIMAuthRolePostOffice>();

    }

but when i execute

Add-Migration

the generated File is :

migrationBuilder.CreateTable(
                name: "DIMAuthOffices",
                columns: table => new
                {
                    ID = table.Column<int>(type: "int", nullable: false)
                        .Annotation("SqlServer:Identity", "1, 1"),
                    Title = table.Column<string>(type: "nvarchar(max)", nullable: false),
                    UserNameManager = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
                    ParentID = table.Column<int>(type: "int", nullable: false),
                    UserManagerUserName = table.Column<string>(type: "nvarchar(50)", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_DIMAuthOffices", x => x.ID);
                    table.ForeignKey(
                        name: "FK_DIMAuthOffices_DIMAuthOffices_ParentID",
                        column: x => x.ParentID,
                        principalTable: "DIMAuthOffices",
                        principalColumn: "ID");
                    table.ForeignKey(
                        name: "FK_DIMAuthOffices_DIMAuthUsers_UserManagerUserName",
                        column: x => x.UserManagerUserName,
                        principalTable: "DIMAuthUsers",
                        principalColumn: "UserName");
                });

wrong line is :

ParentID = table.Column(type: "int", nullable: false),

the generated File is Wrong and property ParentID set to nullable:false but this should be true ...
why ???

Body:
Doesn't repro for me on EF Core 6.  eg

public class DIMAuthOffice
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }
    public string Title { get; set; }
    [StringLength(50)]
    [Required]
    public string UserNameManager { get; set; }
    public int? ParentID { get; set; }
    [ForeignKey(nameof(ParentID))]
    public DIMAuthOffice OfficeParent { get; set; }
    public List<DIMAuthOffice> OfficeChilds { get; set; } = new List<DIMAuthOffice>();

}

creates an initial migration of:

    migrationBuilder.CreateTable(
        name: "DIMAuthOffice",
        columns: table => new
        {
            ID = table.Column<int>(type: "int", nullable: false)
                .Annotation("SqlServer:Identity", "1, 1"),
            Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
            UserNameManager = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
            ParentID = table.Column<int>(type: "int", nullable: true)
        },
        constraints: table =>
        {
            table.PrimaryKey("PK_DIMAuthOffice", x => x.ID);
            table.ForeignKey(
                name: "FK_DIMAuthOffice_DIMAuthOffice_ParentID",
                column: x => x.ParentID,
                principalTable: "DIMAuthOffice",
                principalColumn: "ID");
        });


问:
How to log "model time elapsed" in Anylogic?
How to log the amount of time elapsed with respect to model runtime, so that when I fast-forward the model run, the time that I print reflect that?
I have tried:

```<code>Timestamp timestamp = new Timestamp(System.currentTimeMillis());
</code>```

as well as:

```<code>time(MINUTE);
</code>```

While the first one captures Systems time, the second one also does not increase proportionally when I increase the run speed.
I am assuming, when I increase the run speed of the model, the model effectively start simulating for future!
For example, when model time unit is in minutes and I increase the model run speed to 50x, it means 1 minutes elapsed in real world means 50 minutes elapsed in model world.

答:
Simply call traceln(time()) to get the elapsed model time in the model time units.

To get it in a specific time unit like minutes, call traceln(time(MINUTE)).

What do are doing is to call the real-world time from your computer clock, 100% independent of the model time

To understand the difference between virtual model time and real-world time, see the help.

Body:
How to log the amount of time elapsed with respect to model runtime, so that when I fast-forward the model run, the time that I print reflect that?
I have tried:

Timestamp timestamp = new Timestamp(System.currentTimeMillis());

as well as:

time(MINUTE);

While the first one captures Systems time, the second one also does not increase proportionally when I increase the run speed.
I am assuming, when I increase the run speed of the model, the model effectively start simulating for future!
For example, when model time unit is in minutes and I increase the model run speed to 50x, it means 1 minutes elapsed in real world means 50 minutes elapsed in model world.


问:
Angular 7 - Use BehaviorSubject for Publishing API Results to All Components
I have an API call that returns data about the current user (i.e., username, full name, authorization group memberships, email address, etc.). I would like to only call this API once per user session and have its data shared among all components.

I don't want to rely upon localStorage, since I don't want this data to be modifiable by the user. I am trying to use a BehaviorSubject and have tried following a number of examples, but I keep receiving the initial value (null) when trying to access it via my components.

```<code>// HTTP Service:
getUserData() {
  const url = `${baseUrl}/api/users/`;
  return this.httpClient.get<UserData>(url).toPromise();
}
</code>```

```<code>// Utils Service
export class UtilsService {
  private userDataSubject: BehaviorSubject<UserData>;

  constructor(
    private httpService: HttpService,
  ) {
    this.userDataSubject = new BehaviorSubject<UserData>(null);
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject.next(userData);
    console.log(this.userDataSubject.value); // Properly returns the data I want
  }

  public get userDataValue(): UserData {
    return this.userDataSubject.value;
  }
</code>```

```<code>// Component
  ngOnInit() {
    this.userData = this.utils.userDataValue; // This is the variable I need to set in my component.
    console.log(this.userData);               // Returns null
    console.log(this.utils.userDataValue);    // Also returns null
  }

</code>```

I have also tried using an async function for userDataValue():

```<code>async userDataValue(): Promise<UserData> {
    return this.userDataSubject.value;
  }
</code>```

And modified my component:

```<code>async ngOnInit() {
    this.userData = await this.utils.userDataValue();
    console.log(this.userData);                    // Still returns null
    console.log(await this.utils.userDataValue()); // Still returns null
  }

</code>```

So far, I can only make this work if I avoid using a BehaviorSubject and call the API in each component, but that seems like it shouldn't be necessary. I'd greatly appreciate any guidance in how I can make this work. Thanks.

答:
Here is a little improvement of alexortizl's answer:

Instead of using the BehaviorSubject<> you should use the ReplaySubject<> of size 1. Why?

A BehaviorSubject must be initialized with a value. In your code, it is a null. That means: All subscribers must handle the null (like in alexortizl's answer, the if(date === null)-line).

On the other hand, a ReplaySubject of the size one will act like the BehaviorSubject, but doesn't have initial value. All subscribers will not get any value until the first correct value was emitted. Read this for a deeper dive -> Subject vs BehaviorSubject vs ReplaySubject in Angular

So, you code will look like this:

Service

export class UtilsService {
  // we set the type to "Subject" to hide the actual ReplaySubject
  public userDataSubject$: Subject<UserData> = new ReplaySubject(1);

  constructor(private httpService: HttpService) {
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject$.next(userData);
  }
```
<h3>Component.ts</h3>
<pre class="lang-js prettyprint-override"><code>ngOnInit() {
  this.utils.userDataSubject$.subscribe((data) => {
    console.log(data);
     // component logic to use your data
     // this will be called every time userDataSubject receives a new value
  });
}
</code>```

Component.html

... or even better with the async-pipe. Then you don't have to unsubscribe and it can improve the Change Detection of Angular. Deep dive -> “SEEING” ANGULAR CHANGE DETECTION IN ACTION

<ng-container *ngIf="utils.userDataSubject$ | async as userData">
    Hello {{ userData.firstName }} {{ userData.lastName }}
</ng-container>
```

Body:
I have an API call that returns data about the current user (i.e., username, full name, authorization group memberships, email address, etc.). I would like to only call this API once per user session and have its data shared among all components.

I don't want to rely upon localStorage, since I don't want this data to be modifiable by the user. I am trying to use a BehaviorSubject and have tried following a number of examples, but I keep receiving the initial value (null) when trying to access it via my components.

// HTTP Service:
getUserData() {
  const url = `${baseUrl}/api/users/`;
  return this.httpClient.get<UserData>(url).toPromise();
}

// Utils Service
export class UtilsService {
  private userDataSubject: BehaviorSubject<UserData>;

  constructor(
    private httpService: HttpService,
  ) {
    this.userDataSubject = new BehaviorSubject<UserData>(null);
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject.next(userData);
    console.log(this.userDataSubject.value); // Properly returns the data I want
  }

  public get userDataValue(): UserData {
    return this.userDataSubject.value;
  }

// Component
  ngOnInit() {
    this.userData = this.utils.userDataValue; // This is the variable I need to set in my component.
    console.log(this.userData);               // Returns null
    console.log(this.utils.userDataValue);    // Also returns null
  }

I have also tried using an async function for userDataValue():

async userDataValue(): Promise<UserData> {
    return this.userDataSubject.value;
  }

And modified my component:

async ngOnInit() {
    this.userData = await this.utils.userDataValue();
    console.log(this.userData);                    // Still returns null
    console.log(await this.utils.userDataValue()); // Still returns null
  }

So far, I can only make this work if I avoid using a BehaviorSubject and call the API in each component, but that seems like it shouldn't be necessary. I'd greatly appreciate any guidance in how I can make this work. Thanks.

Body:
Here is a little improvement of alexortizl's answer:

Instead of using the BehaviorSubject<> you should use the ReplaySubject<> of size 1. Why?

A BehaviorSubject must be initialized with a value. In your code, it is a null. That means: All subscribers must handle the null (like in alexortizl's answer, the if(date === null)-line).

On the other hand, a ReplaySubject of the size one will act like the BehaviorSubject, but doesn't have initial value. All subscribers will not get any value until the first correct value was emitted. Read this for a deeper dive -> Subject vs BehaviorSubject vs ReplaySubject in Angular

So, you code will look like this:

Service

export class UtilsService {
  // we set the type to "Subject" to hide the actual ReplaySubject
  public userDataSubject$: Subject<UserData> = new ReplaySubject(1);

  constructor(private httpService: HttpService) {
    this.setUserData();
  }

  async setUserData() {
    let userData: UserData = await this.httpService.getUserData();
    this.userDataSubject$.next(userData);
  }

Component.ts

ngOnInit() {
  this.utils.userDataSubject$.subscribe((data) => {
    console.log(data);
     // component logic to use your data
     // this will be called every time userDataSubject receives a new value
  });
}

Component.html

... or even better with the async-pipe. Then you don't have to unsubscribe and it can improve the Change Detection of Angular. Deep dive -> “SEEING” ANGULAR CHANGE DETECTION IN ACTION

<ng-container *ngIf="utils.userDataSubject$ | async as userData">
    <span>Hello {{ userData.firstName }} {{ userData.lastName }}</span>
</ng-container>


问:
Skill stats are changing in a weird way
My problem: skill stats are changing in a weird way

They are changing in all fields not one.

The numbers are weird.
Output is 1, 111112 and 1.111121111121111e+35, instead of 1, 2, 3, ...

My js code:

```<code>var skillcount = 15;

// Dodawanie umiejętności

$('.skill-plus div img').click(function() {
    if (skillcount > 0) {
        var new_skillstat = parseInt($('td.skill-plus').closest('.skill-stat').text(),0) + 1;
        $('td.skill-plus').closest('.skill-stat').text(new_skillstat);
        $('.skill-item').val(new_skillstat);
        skillcount--;
        $('.abilities').text(skillcount);
        $('.register-abilities').val(skillcount);
    }
});
</code>```

HTML:

```<code><?php
    $showSkills = $databasecon->getSome('*', 'skills', 'skill_cat', 0);
    while($showSkill = mysqli_fetch_array($showSkills)) {
?>
    <tr class="ability-record">
        <td><?php echo $showSkill['skill_name']; ?></td>
        <td class="skill-stat">0</td>
        <td class="skill-plus">
            <div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
            <td class="skill-minus">
                <div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
                <input type="hidden" name="skill-<?php echo $showSkill['id']; ?>" class="skill-item" value="0">
            </td>
        </td>
    </tr>

<?php
    }
?>
</code>```

答:
It is a bit more complex than you thought

I delegate from the ability record

I do not allow to go negative on skill

Your HTML is invalid

var skillcount = 15;

// Dodawanie umiejętności

$('.ability-record img').on('click', function() {
  const $row = $(this).closest('tr');
  const skillValue = $(this).closest('div').is('.stat-plus') ? 1 : -1
  let new_skillstat = +$row.find('.skill-stat').text() + skillValue;
  if (new_skillstat < 0) return; // negative
  $row.find('.skill-stat').text(new_skillstat);
  $row.find('.skill-item').val(new_skillstat);
  skillcount += skillValue * -1; // invert
  $('.abilities').text(skillcount);
  // $('.register-abilities').val(skillcount);
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tbody>
    <tr class="ability-record">
      <td>
        Skill 1
      </td>
      <td class="skill-stat">0</td>
      <td class="skill-plus">
        <div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>

        <div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
        <input type="hidden" name="skill-skill-1" class="skill-item" value="0" />
      </td>
    </tr>

    <tr class="ability-record">
      <td>
        Skill 2
      </td>
      <td class="skill-stat">0</td>
      <td class="skill-plus">
        <div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
        <div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
        <input type="hidden" name="skill-skill-1" class="skill-item" value="0">
      </td>
    </tr>

  </tbody>
</table>
<span class="abilities"></span></code>```

I wanted to stop when using too much skillCount but this did not work as I thought

```<code>const sum = $('.skill-stat')
.map(function() { return +this.textContent})
.get()
.reduce((a,b)=>a+b)
if (skillcount-sum <= 0) return; // negative
</code>```

Title: Skill stats are changing in a weird way

Body:
My problem: skill stats are changing in a weird way

They are changing in all fields not one.

The numbers are weird.
Output is 1, 111112 and 1.111121111121111e+35, instead of 1, 2, 3, ...

My js code:

var skillcount = 15;

// Dodawanie umiejętności

$('.skill-plus div img').click(function() {
    if (skillcount > 0) {
        var new_skillstat = parseInt($('td.skill-plus').closest('.skill-stat').text(),0) + 1;
        $('td.skill-plus').closest('.skill-stat').text(new_skillstat);
        $('.skill-item').val(new_skillstat);
        skillcount--;
        $('.abilities').text(skillcount);
        $('.register-abilities').val(skillcount);
    }
});

HTML:

<?php
    $showSkills = $databasecon->getSome('*', 'skills', 'skill_cat', 0);
    while($showSkill = mysqli_fetch_array($showSkills)) {
?>

        <?php echo $showSkill['skill_name']; ?>
        0

                <input type="hidden" name="skill-<?php echo $showSkill['id']; ?>" class="skill-item" value="0">

<?php
    }
?>

Body:
It is a bit more complex than you thought

I delegate from the ability record

I do not allow to go negative on skill

Your HTML is invalid

var skillcount = 15;

// Dodawanie umiejętności

$('.ability-record img').on('click', function() {
  const $row = $(this).closest('tr');
  const skillValue = $(this).closest('div').is('.stat-plus') ? 1 : -1
  let new_skillstat = +$row.find('.skill-stat').text() + skillValue;
  if (new_skillstat < 0) return; // negative
  $row.find('.skill-stat').text(new_skillstat);
  $row.find('.skill-item').val(new_skillstat);
  skillcount += skillValue * -1; // invert
  $('.abilities').text(skillcount);
  // $('.register-abilities').val(skillcount);
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tbody>
    <tr class="ability-record">
      <td>
        Skill 1
      </td>
      <td class="skill-stat">0</td>
      <td class="skill-plus">
        <div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>

        <div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
        <input type="hidden" name="skill-skill-1" class="skill-item" value="0" />
      </td>
    </tr>

    <tr class="ability-record">
      <td>
        Skill 2
      </td>
      <td class="skill-stat">0</td>
      <td class="skill-plus">
        <div class="stat-plus"><img src="images/plus.png" alt="Plus"></div>
        <div class="stat-minus"><img src="images/minus.png" alt="Minus"></div>
        <input type="hidden" name="skill-skill-1" class="skill-item" value="0">
      </td>
    </tr>

  </tbody>
</table>
<span class="abilities"></span>

I wanted to stop when using too much skillCount but this did not work as I thought

const sum = $('.skill-stat')
.map(function() { return +this.textContent})
.get()
.reduce((a,b)=>a+b)
if (skillcount-sum <= 0) return; // negative


问:
Hide Navbar on mobile after a link is clicked
I'm building a small website and I'd like to hide the mobile navbar after a link is clicked.
I've found some similar questions in this forum: tried hide() and slideup() but it works for the very first link clicked, then I can't re-open my navbar.

The idea is to automatically close the navbar once a link is clicked to simplify and make the website more pleasant.

Here the html of my navbar:

        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
          Toggle navigation

        </button>

01 : Home

02 : The Project

03 : About us

04 : Our Goal

05 : Faq

  ```

答:
document.getElementById('sr-only').addEventListener('click',myFunction)

function myFunction(){
   let nav=document.getElementById('navbar-collapse')
   if(nav.style.display=="" || nav.style.display=='block')
   nav.style.display = 'none'
   else nav.style.display='block'
   }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><nav class="navbar navbar-fixed-top navbar-inverse">
    <div class="container">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
          <span id="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>

      <div class="collapse navbar-collapse" id="navbar-collapse">
        <ul class="nav navbar-nav ">
          <li>01 : Home</li>
          <li>02 : The Project</li>
          <li>03 : About us</li>
          <li>04 : Our Goal</li>
          <li>05 : Faq</li>
        </ul>

      </div>
    </div>
  </nav></code>```

Body:
document.getElementById('sr-only').addEventListener('click',myFunction)

function myFunction(){
   let nav=document.getElementById('navbar-collapse')
   if(nav.style.display=="" || nav.style.display=='block')
   nav.style.display = 'none'
   else nav.style.display='block'
   }

<nav class="navbar navbar-fixed-top navbar-inverse">
    <div class="container">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
          <span id="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>

      <div class="collapse navbar-collapse" id="navbar-collapse">
        <ul class="nav navbar-nav ">
          <li><a class="click" href="./index.html" title="">01 : Home</a></li>
          <li><a class="click" href="#thedavid" title="">02 : The Project</a></li>
          <li><a class="click" href="#aboutus" title="">03 : About us</a></li>
          <li><a class="click" href="#roadmap" title="">04 : Our Goal</a></li>
          <li><a class="click" href="#faq" title="">05 : Faq</a></li>
        </ul>

      </div>
    </div>
  </nav>


问:
Create user with other mail provider in Azure AD B2C (gmail,etc...)
I used Microsoft Graph API PHP SDK to add user in my Azure Active Directory B2C. I managed to create users with a userPrincipalName like name@mytenantid.onmicrosoft.com.

I wasn't able to add users with a GMail address such as john.doe@gmail.com.

I tried to add the signInNames collection but I got the following response:

```<code>Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error:
POST https://graph.microsoft.com/v1.0/users resulted in a 400 Bad Request
response:
   { "error": {
       "code": "Request_BadRequest",
       "message": "Invalid property 'signInNames'.",
       "innerError": (truncated...)
</code>```

Here is my JSON request body :

{
    "accountEnabled": true,
    "displayName": "John Doe",
    "userPrincipalName": "john@doe.fr",
    "creationType": "LocalAccount",
    "passwordProfile" : {
        "forceChangePasswordNextSignIn": true,
        "password": "P@!ssWor?D"
    },
    "signInNames": [
        {
            "type": "emailAddress",
            "value": "john@doe.fr"
        }
     ]
}
```

答:
In case if someone will still have the same problem, in MS Graph Api you can use "identities" instead of "signInNames" and your JSON will look like</p>
```<code>{
   "accountEnabled":true,
   "displayName":"John Doe",
   "userPrincipalName":"john@doe.fr",
   "creationType":"LocalAccount",
   "passwordProfile":{
      "forceChangePasswordNextSignIn":true,
      "password":"P@!ssWor?D"
   },
   "identities":[
      {
         "signInType":"emailAddress",
         "issuer":"<your tenant domain name>",
         "issuerAssignedId":"john@doe.fr"
      }
   ]
}
</code>```

Body:
I used Microsoft Graph API PHP SDK to add user in my Azure Active Directory B2C. I managed to create users with a userPrincipalName like name@mytenantid.onmicrosoft.com.

I wasn't able to add users with a GMail address such as john.doe@gmail.com.

I tried to add the signInNames collection but I got the following response:

Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error:
POST https://graph.microsoft.com/v1.0/users resulted in a 400 Bad Request
response:
   { "error": {
       "code": "Request_BadRequest",
       "message": "Invalid property 'signInNames'.",
       "innerError": (truncated...)

Here is my JSON request body :

{
    "accountEnabled": true,
    "displayName": "John Doe",
    "userPrincipalName": "john@doe.fr",
    "creationType": "LocalAccount",
    "passwordProfile" : {
        "forceChangePasswordNextSignIn": true,
        "password": "P@!ssWor?D"
    },
    "signInNames": [
        {
            "type": "emailAddress",
            "value": "john@doe.fr"
        }
     ]
}

Body:
In case if someone will still have the same problem, in MS Graph Api you can use "identities" instead of "signInNames" and your JSON will look like

{
   "accountEnabled":true,
   "displayName":"John Doe",
   "userPrincipalName":"john@doe.fr",
   "creationType":"LocalAccount",
   "passwordProfile":{
      "forceChangePasswordNextSignIn":true,
      "password":"P@!ssWor?D"
   },
   "identities":[
      {
         "signInType":"emailAddress",
         "issuer":"<your tenant domain name>",
         "issuerAssignedId":"john@doe.fr"
      }
   ]
}


问:
No communication between electron app and user AddData on production
I created an electron app that has user configuration/settings (changing of theme, tracking and persisting window's current size and position). I saved the json files that contained all of these in user AppData (app.getPath('userData')) working well on development but after being packaged with electron-builder, the app no longer communicates the AppData. Tried to change the theme but the new colors could not be written in AppData, size and position not changing. Frustrated ...

Please what next should I do if I must use the AppData

```<code>const { app, BrowserWindow, ipcMain } = require("electron");
let isDev = require('electron-is-dev');
const path = require('path');
const fs = require('fs');
const { setColors } = require('./ipc');

const userDir = app.getPath('userData');

let isConfigDir = fs.existsSync(path.join(userDir, 'config'));
let isSizeDir = fs.existsSync(path.join(userDir, 'config/size.json'))
let isPosDir = fs.existsSync(path.join(userDir, 'config/pos.json'));
let isColorDir = fs.existsSync(path.join(userDir, 'config/colors.json'));

//create config dir if not already exists
if(!isConfigDir){
    fs.mkdirSync(path.join(userDir, '/config'))
}

//check and create config files if not already exist
let pos;
if(!isPosDir){
    let pos_ = {"x":636,"y":0};
    fs.writeFileSync(path.join(userDir, 'config/pos.json'), JSON.stringify(pos_));
    pos = pos_
}else{
    pos = JSON.parse(fs.readFileSync(path.join(userDir, 'config/pos.json'), "utf8"))
}

let size
if(!isSizeDir){
    let size_ = {"width":701,"height":768}
    fs.writeFileSync(path.join(userDir, 'config/size.json'), JSON.stringify(size_));
    size = size_;
}else{
    size = JSON.parse(fs.readFileSync(path.join(userDir, 'config/size.json'), "utf8"))
}

ipcMain.handle("getColors", (event, args)=>{
    let colors;
    if(!isColorDir){
        let colors_ = {"bg":"gold","text":"#000"}
        fs.writeFileSync(path.join(userDir, 'config/colors.json'), JSON.stringify(colors_));
        colors = colors_
        return colors;
    }else{
        colors = JSON.parse(fs.readFileSync(path.join(userDir, 'config/colors.json'), "utf8"));
        return colors;
    }
})

let win;
function createWin(){
    win = new BrowserWindow({
        width:size.width,
        height: size.height,
        x: pos.x,
        y: pos.y,
        title: 'BMS',
        webPreferences:{
            preload: path.join(__dirname, "preload.js")
        }
    });
    isDev ? win.loadURL('http://localhost:3000') : win.loadFile('views/build/index.html')

    win.on("closed", ()=>win = null);

    // set window size in file size.json when the system resized
    win.on('resized', ()=>{
        let size = {
            width: win.getBounds().width,
            height: win.getBounds().height,
        }
        fs.writeFileSync(path.join(userDir, 'config/size.json'), JSON.stringify(size))
    })

    // set window position in file size.json when the window moves
    win.on('move', ()=>{
        let pos = {
            x: win.getBounds().x,
            y: win.getBounds().y
        }
        fs.writeFileSync(path.join(userDir, 'config/pos.json'), JSON.stringify(pos))
    })
}

app.on("ready", ()=>{
    //create window
    createWin();

    setColors(userDir)

})

app.on("window-all-closed", ()=>{
    if(process.platform !== 'darwin'){
        app.quit()
    }
})
app.on('active', ()=>{
    if(win===null){
        createWin()
    }
})
</code>```

答:
You should take a look at the electron-json-storage package. The package will handle where to put the persisent data depending on the user OS system, and the JSON parsing. You just need to call the package with whatever JS Object you want to store.

I am using this package in my differents electron projects, and it really makes it easy. I recommand using it instead of struggling with the 'fs' Node API.

Body:
I created an electron app that has user configuration/settings (changing of theme, tracking and persisting window's current size and position). I saved the json files that contained all of these in user AppData (app.getPath('userData')) working well on development but after being packaged with electron-builder, the app no longer communicates the AppData. Tried to change the theme but the new colors could not be written in AppData, size and position not changing. Frustrated ...

Please what next should I do if I must use the AppData

const { app, BrowserWindow, ipcMain } = require("electron");
let isDev = require('electron-is-dev');
const path = require('path');
const fs = require('fs');
const { setColors } = require('./ipc');

const userDir = app.getPath('userData');

let isConfigDir = fs.existsSync(path.join(userDir, 'config'));
let isSizeDir = fs.existsSync(path.join(userDir, 'config/size.json'))
let isPosDir = fs.existsSync(path.join(userDir, 'config/pos.json'));
let isColorDir = fs.existsSync(path.join(userDir, 'config/colors.json'));

//create config dir if not already exists
if(!isConfigDir){
    fs.mkdirSync(path.join(userDir, '/config'))
}

//check and create config files if not already exist
let pos;
if(!isPosDir){
    let pos_ = {"x":636,"y":0};
    fs.writeFileSync(path.join(userDir, 'config/pos.json'), JSON.stringify(pos_));
    pos = pos_
}else{
    pos = JSON.parse(fs.readFileSync(path.join(userDir, 'config/pos.json'), "utf8"))
}

let size
if(!isSizeDir){
    let size_ = {"width":701,"height":768}
    fs.writeFileSync(path.join(userDir, 'config/size.json'), JSON.stringify(size_));
    size = size_;
}else{
    size = JSON.parse(fs.readFileSync(path.join(userDir, 'config/size.json'), "utf8"))
}

ipcMain.handle("getColors", (event, args)=>{
    let colors;
    if(!isColorDir){
        let colors_ = {"bg":"gold","text":"#000"}
        fs.writeFileSync(path.join(userDir, 'config/colors.json'), JSON.stringify(colors_));
        colors = colors_
        return colors;
    }else{
        colors = JSON.parse(fs.readFileSync(path.join(userDir, 'config/colors.json'), "utf8"));
        return colors;
    }
})

let win;
function createWin(){
    win = new BrowserWindow({
        width:size.width,
        height: size.height,
        x: pos.x,
        y: pos.y,
        title: 'BMS',
        webPreferences:{
            preload: path.join(__dirname, "preload.js")
        }
    });
    isDev ? win.loadURL('http://localhost:3000') : win.loadFile('views/build/index.html')

    win.on("closed", ()=>win = null);

    // set window size in file size.json when the system resized
    win.on('resized', ()=>{
        let size = {
            width: win.getBounds().width,
            height: win.getBounds().height,
        }
        fs.writeFileSync(path.join(userDir, 'config/size.json'), JSON.stringify(size))
    })

    // set window position in file size.json when the window moves
    win.on('move', ()=>{
        let pos = {
            x: win.getBounds().x,
            y: win.getBounds().y
        }
        fs.writeFileSync(path.join(userDir, 'config/pos.json'), JSON.stringify(pos))
    })
}

app.on("ready", ()=>{
    //create window
    createWin();

    setColors(userDir)

})

app.on("window-all-closed", ()=>{
    if(process.platform !== 'darwin'){
        app.quit()
    }
})
app.on('active', ()=>{
    if(win===null){
        createWin()
    }
})


问:
Kafka replication issue
I am using a 3 broker kafka.
If I stop the third node: no problem, I can consume LOGS from node 1 or 2.
If I stop the second node : no problem, I can consume LOGS from node 1 or 3.
If I stop the first node : I am not able to consume anything.

When I restart kafka-runner service . Logs are here and was wrote properly.

my topic configuration is:
Topic: log_topic    TopicId: xxx    PartitionCount: 32  ReplicationFactor: 3    Configs: segment.bytes=1073741824,retention.ms=7200000
Topic: log_topic    Partition: 0    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 1    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 2    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 3    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 4    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 5    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 6    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 7    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 8    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 9    Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 10   Leader: 2   Replicas: 2,3,1 Isr: 2,3,1
Topic: log_topic    Partition: 11   Leader: 3   Replicas: 3,1,2 Isr: 2,3,1
Topic: log_topic    Partition: 12   Leader: 3   Replicas: 1,3,2 Isr: 2,3,1
Topic: log_topic    Partition: 13   Leader: 2   Replicas: 2,1,3 Isr: 2,3,1
Topic: log_topic    Partition: 14   Leader: 3   Replicas: 3,2,1 Isr: 2,3,1
Topic: log_topic    Partition: 15   Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 16   Leader: 2   Replicas: 2,3,1 Isr: 2,3,1
Topic: log_topic    Partition: 17   Leader: 3   Replicas: 3,1,2 Isr: 2,3,1
Topic: log_topic    Partition: 18   Leader: 3   Replicas: 1,3,2 Isr: 2,3,1
Topic: log_topic    Partition: 19   Leader: 2   Replicas: 2,1,3 Isr: 2,3,1
Topic: log_topic    Partition: 20   Leader: 3   Replicas: 3,2,1 Isr: 2,3,1
Topic: log_topic    Partition: 21   Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 22   Leader: 2   Replicas: 2,3,1 Isr: 2,3,1
Topic: log_topic    Partition: 23   Leader: 3   Replicas: 3,1,2 Isr: 2,3,1
Topic: log_topic    Partition: 24   Leader: 3   Replicas: 1,3,2 Isr: 2,3,1
Topic: log_topic    Partition: 25   Leader: 2   Replicas: 2,1,3 Isr: 2,3,1
Topic: log_topic    Partition: 26   Leader: 3   Replicas: 3,2,1 Isr: 2,3,1
Topic: log_topic    Partition: 27   Leader: 2   Replicas: 1,2,3 Isr: 2,3,1
Topic: log_topic    Partition: 28   Leader: 2   Replicas: 2,3,1 Isr: 2,3,1
Topic: log_topic    Partition: 29   Leader: 3   Replicas: 3,1,2 Isr: 2,3,1
Topic: log_topic    Partition: 30   Leader: 3   Replicas: 1,3,2 Isr: 2,3,1
Topic: log_topic    Partition: 31   Leader: 2   Replicas: 2,1,3 Isr: 2,3,1

When I stop leader node. leader changes properly.

Any Idea?

答:
This seems like a configuration issue with the __consumer_offsets topic.

_consumer_offsets is used to store information about committed offsets for each topic:partition per group of consumers (groupID)

Whenever a consumer in a group reads data from kafka, it periodically stores the information on the point till the data is read in a special topic called __consumer_offsets. This is done so that the consumer can resume from its last position in case of failure.

Issue

The replication factor for __consumer_offsets topic would have been set to 1 and all the partitions for the topic would also be present in broker 1.

You can describe the __consumer_offsets topic to verify above.
If this is the case, then the easiest way to resolve the issue would be to delete the __consumer_offsets topic and recreate it with the desired replication factor.

If deletion is not an option, then following the instructions in the thread below

How to change the number of replicas of a Kafka topic?

Title: Kafka replication issue


问:
How I can display the number of items on the page I am looking at? (using liquid / ruby on rails / shopify)
Does anyone know how I can display the number of items on the page I am looking at?
I only know how to display the total number of items, using {{ paginate.items }}

My goal is to display the following message...
"Showing 1 to 8 products from 100" and have this update each time you go to the next page...
"Showing 9 to 16 products from 100"...

```<code>      <div>
        <p class="text-sm text-gray-700">
          Showing
          <span class="font-medium">{{ what goes here? }}</span>
          to
          <span class="font-medium">{{ what goes here? }}</span>
          products from
          <span class="font-medium">{{ paginate.items }}</span>
        </p>
      </div>

</code>```

答:
Thank you. I have figured something out but it doesn't work for the last page because the page has less than {{ paginate.page_size }}.

{{ paginate.page_size }} is the max number of products the page can hold, rather than the actual number of products the page is holding. How can I get the latter?

```<code> <p class="text-sm text-gray-700">
  Showing
  {% assign firstNumber = paginate.current_offset | plus: 1 %}
  <span class="font-medium">{{ firstNumber }}</span>
  to
  {% unless current_page == 1 %}
    <span class="font-medium">{{ paginate.current_offset | plus: paginate.page_size }}</span>
    {% else %}
    <span class="font-medium">{{ paginate.page_size }}</span>
  {% endunless %}
  products from
  <span class="font-medium">{{ paginate.items }}</span>
</p>
</code>```

Body:
Does anyone know how I can display the number of items on the page I am looking at?
I only know how to display the total number of items, using {{ paginate.items }}

My goal is to display the following message...
"Showing 1 to 8 products from 100" and have this update each time you go to the next page...
"Showing 9 to 16 products from 100"...

          Showing
          {{ what goes here? }}
          to
          {{ what goes here? }}
          products from
          {{ paginate.items }}

Body:
Thank you. I have figured something out but it doesn't work for the last page because the page has less than {{ paginate.page_size }}.

{{ paginate.page_size }} is the max number of products the page can hold, rather than the actual number of products the page is holding. How can I get the latter?

 <p class="text-sm text-gray-700">
  Showing
  {% assign firstNumber = paginate.current_offset | plus: 1 %}
  <span class="font-medium">{{ firstNumber }}</span>
  to
  {% unless current_page == 1 %}
    <span class="font-medium">{{ paginate.current_offset | plus: paginate.page_size }}</span>
    {% else %}
    <span class="font-medium">{{ paginate.page_size }}</span>
  {% endunless %}
  products from
  <span class="font-medium">{{ paginate.items }}</span>
</p>


问:
Count by group using dplyr, but also count 0s
I'm making a count table for 2 data frames. One looks like this:

```<code>table1 <- data.table("Col1" = c("Al", "Al", "Al", "Cu", "Cu", "Cu", "Pb", "Pb",
"Pb"), "Col2" = c("F", "UF", "P", "F", "UF", "P", "F", "UF", "P"), "Col3" = c("C",
"UC", "<", "C", "UC", "<", "C", "UC", "<"))

table2 <- data.table("Col1" = c("Al", "Al", "Cu", "Pb", "Pb", "Pb"), "Col2" = c("F",
"UF", "F", "F", "UF", "P"), "Col3" = c("C", "UC", "<", "C", "UC", "<"))
</code>```

I'd create a count table for table1 and table2 like this:

```<code>table1 %>% group_by(Col1, Col2, Col3) %>% tally()

# A tibble: 9 x 4
# Groups:   Col1, Col2 [9]
  Col1  Col2  Col3      n
  <chr> <chr> <chr> <int>
1 Al    F     C         1
2 Al    P     <         1
3 Al    UF    UC        1
4 Cu    F     C         1
5 Cu    P     <         1
6 Cu    UF    UC        1
7 Pb    F     C         1
8 Pb    P     <         1
9 Pb    UF    UC        1

table2 %>% group_by(Col1, Col2, Col3) %>% tally()
# A tibble: 6 x 4
# Groups:   Col1, Col2 [6]
  Col1  Col2  Col3      n
  <chr> <chr> <chr> <int>
1 Al    F     C         1
2 Al    UF    UC        1
3 Cu    F     <         1
4 Pb    F     C         1
5 Pb    P     <         1
6 Pb    UF    UC        1
</code>```

But I'd like the count table for table2 to have the 0 counts with the combinations from table1, not remove them completely so it doesn't show the 0 counts. Is there a way I can do this with dplyr or a different package?

Thank you for your help!

答:
1)  Append an n=1 column to table2 and an n=0 column to table 1 and then sum n by group.

```<code>table2 %>%
  mutate(n = 1L) %>%
  bind_rows(table1 %>% mutate(n = 0L)) %>%
  group_by(Col1, Col2, Col3) %>%
  summarize(n = sum(n), .groups = "drop")
</code>```

giving:

```<code># A tibble: 10 x 4
   Col1  Col2  Col3      n
   <chr> <chr> <chr> <int>
 1 Al    F     C         1
 2 Al    P     <         0
 3 Al    UF    UC        1
 4 Cu    F     <         1
 5 Cu    F     C         0
 6 Cu    P     <         0
 7 Cu    UF    UC        0
 8 Pb    F     C         1
 9 Pb    P     <         1
10 Pb    UF    UC        1
</code>```

2) This variation gives the same result.

```<code>list(table1, table2) %>%
  bind_rows(.id = "id") %>%
  group_by(Col1, Col2, Col3) %>%
  summarize(n = sum(id == 2L), .groups = "drop")
</code>```

3) This is a data.table only solution.

```<code>rbindlist(list(table1, table2), idcol = TRUE)[,
  .(n = sum(.id == 2L)), by = .(Col1, Col2, Col3)]
</code>```

4) This is a base R solution.

```<code>both <- rbind(transform(table1, n = 0), transform(table2, n = 1))
aggregate(n ~., both, sum)
</code>```

5) This uses SQL.

```<code>library(sqldf)

sqldf("with both as (
    select *, 0 as n from table1
    union all
    select *, 1 as n from table2
  )
  select Col1, Col2, Col3, sum(n) as n
    from both
    group by Col1, Col2, Col3
")
</code>```

Body:
I'm making a count table for 2 data frames. One looks like this:

table1 <- data.table("Col1" = c("Al", "Al", "Al", "Cu", "Cu", "Cu", "Pb", "Pb",
"Pb"), "Col2" = c("F", "UF", "P", "F", "UF", "P", "F", "UF", "P"), "Col3" = c("C",
"UC", "<", "C", "UC", "<", "C", "UC", "<"))

table2 <- data.table("Col1" = c("Al", "Al", "Cu", "Pb", "Pb", "Pb"), "Col2" = c("F",
"UF", "F", "F", "UF", "P"), "Col3" = c("C", "UC", "<", "C", "UC", "<"))

I'd create a count table for table1 and table2 like this:

table1 %>% group_by(Col1, Col2, Col3) %>% tally()

# A tibble: 9 x 4
# Groups:   Col1, Col2 [9]
  Col1  Col2  Col3      n
  <chr> <chr> <chr> <int>
1 Al    F     C         1
2 Al    P     <         1
3 Al    UF    UC        1
4 Cu    F     C         1
5 Cu    P     <         1
6 Cu    UF    UC        1
7 Pb    F     C         1
8 Pb    P     <         1
9 Pb    UF    UC        1

table2 %>% group_by(Col1, Col2, Col3) %>% tally()
# A tibble: 6 x 4
# Groups:   Col1, Col2 [6]
  Col1  Col2  Col3      n
  <chr> <chr> <chr> <int>
1 Al    F     C         1
2 Al    UF    UC        1
3 Cu    F     <         1
4 Pb    F     C         1
5 Pb    P     <         1
6 Pb    UF    UC        1

But I'd like the count table for table2 to have the 0 counts with the combinations from table1, not remove them completely so it doesn't show the 0 counts. Is there a way I can do this with dplyr or a different package?

Thank you for your help!

Body:
1)  Append an n=1 column to table2 and an n=0 column to table 1 and then sum n by group.

table2 %>%
  mutate(n = 1L) %>%
  bind_rows(table1 %>% mutate(n = 0L)) %>%
  group_by(Col1, Col2, Col3) %>%
  summarize(n = sum(n), .groups = "drop")

giving:

# A tibble: 10 x 4
   Col1  Col2  Col3      n
   <chr> <chr> <chr> <int>
 1 Al    F     C         1
 2 Al    P     <         0
 3 Al    UF    UC        1
 4 Cu    F     <         1
 5 Cu    F     C         0
 6 Cu    P     <         0
 7 Cu    UF    UC        0
 8 Pb    F     C         1
 9 Pb    P     <         1
10 Pb    UF    UC        1

2) This variation gives the same result.

list(table1, table2) %>%
  bind_rows(.id = "id") %>%
  group_by(Col1, Col2, Col3) %>%
  summarize(n = sum(id == 2L), .groups = "drop")

3) This is a data.table only solution.

rbindlist(list(table1, table2), idcol = TRUE)[,
  .(n = sum(.id == 2L)), by = .(Col1, Col2, Col3)]

4) This is a base R solution.

both <- rbind(transform(table1, n = 0), transform(table2, n = 1))
aggregate(n ~., both, sum)

5) This uses SQL.

library(sqldf)

sqldf("with both as (
    select *, 0 as n from table1
    union all
    select *, 1 as n from table2
  )
  select Col1, Col2, Col3, sum(n) as n
    from both
    group by Col1, Col2, Col3
")


问:
Can you overlay an image with text using BLOX in Sisense
I want to create a BLOX widget to be used as a banner at the top of my dashboards.  The body of the widget contains an image.  I want to place some text over that image but I am not finding a way to do that.  I can create a second item in the body that contains the text but it is placed below the image.  This is the body of my widget.  I would appreciate any ideas on how to get the text to overlay the image.</p>
```<code>"body": [
    {
        "type": "Container",
        "horizontalAlignment": "center",
        "items": [
            {
                "type": "Image",
                "url": "https://mycompany.com/myimage.png",
                "altText": "Company Name",
                "size": "stretch"
            },
            {
                "type": "TextBlock",
                "id": "DashboardTitle",
                "style": {
                    "color": "#4a0004",
                    "font-weight": "bold",
                    "font-size": 48,
                    "background-color": "white"
                },
                "class": "",
                "text": "Customer Review"
            }
        ]
    }
],
</code>```

答:
You need to use your image as a background image for the Blox. That will allow you to overlay it with text items.
You might need to give the container a background color (rgb(0,0,0,5)) to make the image opaque but that should work for you.
B RGDS
Hendrik</p>

Body:
I want to create a BLOX widget to be used as a banner at the top of my dashboards.  The body of the widget contains an image.  I want to place some text over that image but I am not finding a way to do that.  I can create a second item in the body that contains the text but it is placed below the image.  This is the body of my widget.  I would appreciate any ideas on how to get the text to overlay the image.

"body": [
    {
        "type": "Container",
        "horizontalAlignment": "center",
        "items": [
            {
                "type": "Image",
                "url": "https://mycompany.com/myimage.png",
                "altText": "Company Name",
                "size": "stretch"
            },
            {
                "type": "TextBlock",
                "id": "DashboardTitle",
                "style": {
                    "color": "#4a0004",
                    "font-weight": "bold",
                    "font-size": 48,
                    "background-color": "white"
                },
                "class": "",
                "text": "Customer Review"
            }
        ]
    }
],