问:
Images are not resizing
I am making a gallery website with materializedcss. I am trying to make it so 4 images show up on each row, with them not looking so big, however with what I have written, all the images are displaying in their full size, rather than being minimzed to then be expanded via the materialboxed class. I am unsure if it is a problem with the css I have written, or through the materialboxed class from materialized, but from the jsfiddle, it seems like it is a problem with their class.

https://jsfiddle.net/ptfbkwre/

https://materializecss.com/media.html

```<code><div id="recent">
      <div class="imagetab-grid">
        <img class="materialboxed" src="img/xjErLux.jpg" data-caption="short description. idk. image looks cool!">
      </div>
      <div class="imagetab-grid">
        <img class="materialboxed" src="img/07xoCEp.jpg" data-caption="short description. idk. image looks cool!">
      </div>
      <div class="imagetab-grid">
        <img class="materialboxed" src="img/903IrFQ.jpg" data-caption="short description. idk. image looks cool!">
      </div>
    </div>

.imagetab-grid{
  width: 25%;
  margin: 10px;
  padding: 10px;
}

.imagetab-grid>img {
  width: 100%;
}
</code>```

答:
Hey hope this helps I have forked your Fiddle and modified a little bit and attached the code here.

.imagetab-grid {
  box-sizing: border-box;
  width: 25%;
  padding: 5px;
  float: left;
}

.imagetab-grid img {
  width: 100%;
}

/* Clearfix (clear floats) */
.row::after {
  content: "";
  clear: both;
  display: table;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="recent" class="row">
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://dikxrpw3rdepo.cloudfront.net/wp-content/uploads/2017/01/tbs2_ost_interior_2560x1440.png" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://preppywallpapers.com/wp-content/uploads/2019/01/header2.jpg" data-caption="short description. idk. image looks cool!">
  </div>

</div></code>```

Reference here

Title: Images are not resizing

Body:
I am making a gallery website with materializedcss. I am trying to make it so 4 images show up on each row, with them not looking so big, however with what I have written, all the images are displaying in their full size, rather than being minimzed to then be expanded via the materialboxed class. I am unsure if it is a problem with the css I have written, or through the materialboxed class from materialized, but from the jsfiddle, it seems like it is a problem with their class.

https://jsfiddle.net/ptfbkwre/

https://materializecss.com/media.html

.imagetab-grid{
  width: 25%;
  margin: 10px;
  padding: 10px;
}

.imagetab-grid>img {
  width: 100%;
}

Body:
Hey hope this helps I have forked your Fiddle and modified a little bit and attached the code here.

.imagetab-grid {
  box-sizing: border-box;
  width: 25%;
  padding: 5px;
  float: left;
}

.imagetab-grid img {
  width: 100%;
}

/* Clearfix (clear floats) */
.row::after {
  content: "";
  clear: both;
  display: table;
}

<div id="recent" class="row">
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://dikxrpw3rdepo.cloudfront.net/wp-content/uploads/2017/01/tbs2_ost_interior_2560x1440.png" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://steamuserimages-a.akamaihd.net/ugc/940586530515504757/CDDE77CB810474E1C07B945E40AE4713141AFD76/" data-caption="short description. idk. image looks cool!">
  </div>
  <div class="imagetab-grid">
    <img class="materialboxed" src="https://preppywallpapers.com/wp-content/uploads/2019/01/header2.jpg" data-caption="short description. idk. image looks cool!">
  </div>

</div>

Reference here


来源: stackexchange

问:
FindVisualChild - Get properties of named UI Elements in ItemsControl
I generate UI elements at runtime by using a ItemsControl. The UI generates successfully but if I am unable to get any properties of the generated UI items, such as "Content" for a label, or SelectedItem for a ComboBox. I tried to get these properties by using this tutorial , and these answers but I always get a NullReferenceException.

The ItemsControl in XAML looks like this:

```<code>            <ItemsControl Name="ListOfVideos">
                <ItemsControl.Background>
                    <SolidColorBrush Color="Black" Opacity="0"/>
                </ItemsControl.Background>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="0,0,0,10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="180"/>
                                <ColumnDefinition Width="400"/>
                                <ColumnDefinition Width="200"/>
                            </Grid.ColumnDefinitions>
                            <Image HorizontalAlignment="Left" Height="100" Width="175" x:Name="VideoThumbnailImage" Stretch="Fill" Source="{Binding VideoThumbnailURL}" Grid.Column="0"></Image>
                            <Label x:Name="VideoTitleLabel" Content="{Binding VideoTitleText}" Foreground="White" Grid.Column="1" VerticalAlignment="Top" FontSize="16" FontWeight="Bold"></Label>
                            <Label x:Name="VideoFileSizeLabel" Content="{Binding VideoTotalSizeText}" Foreground="White" FontSize="14" Grid.Column="1" Margin="0,0,0,35" VerticalAlignment="Bottom"></Label>
                            <Label x:Name="VideoProgressLabel" Content="{Binding VideoStatusText}" Foreground="White" FontSize="14" Grid.Column="1" VerticalAlignment="Bottom"></Label>
                            <ComboBox x:Name="VideoComboBox" SelectionChanged="VideoComboBox_SelectionChanged" Grid.Column="2" Width="147.731" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,50" ItemsSource="{Binding VideoQualitiesList}"></ComboBox>
                            <Label Content="Video Quality" Foreground="White" FontSize="14" VerticalAlignment="Top" Grid.Column="2" HorizontalAlignment="Center"></Label>
                            <Label Content="Audio Quality" Foreground="White" FontSize="14" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,27" Grid.Column="2"></Label>
                            <Slider x:Name="VideoAudioSlider" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="147.731" Maximum="{Binding AudioCount}"></Slider>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
</code>```

This is how I generate the UI elements

```<code>public class VideoMetadataDisplay
    {
        public string VideoTitleText { get; set; }
        public int AudioCount { get; set; }
        public string VideoThumbnailURL { get; set; }
        public string VideoStatusText { get; set; }
        public string VideoTotalSizeText { get; set; }
        public List<string> VideoQualitiesList { get; set; }
    }

public partial class PlaylistPage : Page
{
private void GetPlaylistMetadata()
        {

            List<VideoMetadataDisplay> newList = new List<VideoMetadataDisplay>();
            //populate the list
            ListOfVideos.ItemsSource = newList;
        }
}
</code>```

And this is how I'm trying to get the properties of the UI elements

```<code>public class Utils
    {
        public childItem FindVisualChild<childItem>(DependencyObject obj)
     where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                {
                    return (childItem)child;
                }
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
    }

private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UIElement CurrentItem = (UIElement)ListOfVideos.ItemContainerGenerator.ContainerFromItem(ListOfVideos.Items.CurrentItem);
            Utils utils = new Utils();
            ContentPresenter CurrentContentPresenter = utils.FindVisualChild<ContentPresenter>(CurrentItem);
            DataTemplate CurrentDataTemplate = CurrentContentPresenter.ContentTemplate;
            Label VideoTitle = (Label)CurrentDataTemplate.FindName("VideoTitleLabel", CurrentContentPresenter);
            string VideoTitleText = VideoTitle.Content.ToString();
            MessageBox.Show(VideoTitleText);
        }
</code>```

Every time I try to run this, FindVisualChild always returns one of the labels (VideoTitleLabel) instead of returning the ContentPresenter for the currently active item. CurrentDataTemplate is then null and I am unable to get any of the UI elements from it.

答:
It is impossible that FindVisualChild<ContentPresenter> returns a Label instance. FindVisualChild casts the result to ContentPresenter. Since Label is not a ContentPresenter, this would throw an InvalidCastException. But before this, child is childItem would return false in case child is of type Label and the generic parameter type childItem is of type ContentPresenter and therefore a potential null is returned.

Short Version

Accessing the the DataTemplate or looking up controls just to get their bound data is always too complicated. It's always easier to access the data source directly.

ItemsControl.SelectedItem will return the data model for the selected item. You are usually not interested in the containers.

```<code>private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var listView = sender as ListView;
  var item = listView.SelectedItem as VideoMetadataDisplay;
  MessageBox.Show(item.VideoTitleText);
}
</code>```

Your Version (FindVisualChild improved)

FindVisualChild is weakly implemented. It will fail and throw an exception if traversal encounters a child node without children i.e. the parameter obj is null. You have to check the parameter obj for null before invoking VisualTreeHelper.GetChildrenCount(obj), to avoid a null reference.

Also you don't need to search the element by accessing the template. You can look it up directly in the visual tree.

I have modified your FindVisualChild method to search elements by name. I also have turned it into an extension method for convenience:

Extension Method

```<code>public static class Utils
{
  public static bool TryFindVisualChildByName<TChild>(
    this DependencyObject parent,
    string childElementName,
    out TChild childElement,
    bool isCaseSensitive = false)
    where TChild : FrameworkElement
  {
    childElement = null;

    // Popup.Child content is not part of the visual tree.
    // To prevent traversal from breaking when parent is a Popup,
    // we need to explicitly extract the content.
    if (parent is Popup popup)
    {
      parent = popup.Child;
    }

    if (parent == null)
    {
      return false;
    }

    var stringComparison = isCaseSensitive
      ? StringComparison.Ordinal
      : StringComparison.OrdinalIgnoreCase;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(parent, i);
      if (child is TChild resultElement
        && resultElement.Name.Equals(childElementName, stringComparison))
      {
        childElement = resultElement;
        return true;
      }

      if (child.TryFindVisualChildByName(childElementName, out childElement))
      {
        return true;
      }
    }

    return false;
  }
}
</code>```

Example

```<code>private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var listView = sender as ListView;
  object item = listView.SelectedItem;
  var itemContainer = listView.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem;

  if (itemContainer.TryFindVisualChildByName("VideoTitleLabel", out Label label))
  {
    var videoTitleText = label.Content as string;
    MessageBox.Show(videoTitleText);
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I generate UI elements at runtime by using a ItemsControl. The UI generates successfully but if I am unable to get any properties of the generated UI items, such as "Content" for a label, or SelectedItem for a ComboBox. I tried to get these properties by using this tutorial , and these answers but I always get a NullReferenceException.

The ItemsControl in XAML looks like this:

            <ItemsControl Name="ListOfVideos">
                <ItemsControl.Background>
                    <SolidColorBrush Color="Black" Opacity="0"/>
                </ItemsControl.Background>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="0,0,0,10">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="180"/>
                                <ColumnDefinition Width="400"/>
                                <ColumnDefinition Width="200"/>
                            </Grid.ColumnDefinitions>
                            <Image HorizontalAlignment="Left" Height="100" Width="175" x:Name="VideoThumbnailImage" Stretch="Fill" Source="{Binding VideoThumbnailURL}" Grid.Column="0"></Image>

                            <ComboBox x:Name="VideoComboBox" SelectionChanged="VideoComboBox_SelectionChanged" Grid.Column="2" Width="147.731" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="0,0,0,50" ItemsSource="{Binding VideoQualitiesList}"></ComboBox>

                            <Slider x:Name="VideoAudioSlider" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" Width="147.731" Maximum="{Binding AudioCount}"></Slider>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

This is how I generate the UI elements

public class VideoMetadataDisplay
    {
        public string VideoTitleText { get; set; }
        public int AudioCount { get; set; }
        public string VideoThumbnailURL { get; set; }
        public string VideoStatusText { get; set; }
        public string VideoTotalSizeText { get; set; }
        public List<string> VideoQualitiesList { get; set; }
    }

public partial class PlaylistPage : Page
{
private void GetPlaylistMetadata()
        {

            List<VideoMetadataDisplay> newList = new List<VideoMetadataDisplay>();
            //populate the list
            ListOfVideos.ItemsSource = newList;
        }
}

And this is how I'm trying to get the properties of the UI elements

public class Utils
    {
        public childItem FindVisualChild<childItem>(DependencyObject obj)
     where childItem : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is childItem)
                {
                    return (childItem)child;
                }
                else
                {
                    childItem childOfChild = FindVisualChild<childItem>(child);
                    if (childOfChild != null)
                        return childOfChild;
                }
            }
            return null;
        }
    }

private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UIElement CurrentItem = (UIElement)ListOfVideos.ItemContainerGenerator.ContainerFromItem(ListOfVideos.Items.CurrentItem);
            Utils utils = new Utils();
            ContentPresenter CurrentContentPresenter = utils.FindVisualChild<ContentPresenter>(CurrentItem);
            DataTemplate CurrentDataTemplate = CurrentContentPresenter.ContentTemplate;
            Label VideoTitle = (Label)CurrentDataTemplate.FindName("VideoTitleLabel", CurrentContentPresenter);
            string VideoTitleText = VideoTitle.Content.ToString();
            MessageBox.Show(VideoTitleText);
        }

Every time I try to run this, FindVisualChild always returns one of the labels (VideoTitleLabel) instead of returning the ContentPresenter for the currently active item. CurrentDataTemplate is then null and I am unable to get any of the UI elements from it.

Body:
It is impossible that FindVisualChild<ContentPresenter> returns a Label instance. FindVisualChild casts the result to ContentPresenter. Since Label is not a ContentPresenter, this would throw an InvalidCastException. But before this, child is childItem would return false in case child is of type Label and the generic parameter type childItem is of type ContentPresenter and therefore a potential null is returned.

Short Version

Accessing the the DataTemplate or looking up controls just to get their bound data is always too complicated. It's always easier to access the data source directly.

ItemsControl.SelectedItem will return the data model for the selected item. You are usually not interested in the containers.

private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var listView = sender as ListView;
  var item = listView.SelectedItem as VideoMetadataDisplay;
  MessageBox.Show(item.VideoTitleText);
}

Your Version (FindVisualChild improved)

FindVisualChild is weakly implemented. It will fail and throw an exception if traversal encounters a child node without children i.e. the parameter obj is null. You have to check the parameter obj for null before invoking VisualTreeHelper.GetChildrenCount(obj), to avoid a null reference.

Also you don't need to search the element by accessing the template. You can look it up directly in the visual tree.

I have modified your FindVisualChild method to search elements by name. I also have turned it into an extension method for convenience:

Extension Method

public static class Utils
{
  public static bool TryFindVisualChildByName<TChild>(
    this DependencyObject parent,
    string childElementName,
    out TChild childElement,
    bool isCaseSensitive = false)
    where TChild : FrameworkElement
  {
    childElement = null;

    // Popup.Child content is not part of the visual tree.
    // To prevent traversal from breaking when parent is a Popup,
    // we need to explicitly extract the content.
    if (parent is Popup popup)
    {
      parent = popup.Child;
    }

    if (parent == null)
    {
      return false;
    }

    var stringComparison = isCaseSensitive
      ? StringComparison.Ordinal
      : StringComparison.OrdinalIgnoreCase;

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(parent, i);
      if (child is TChild resultElement
        && resultElement.Name.Equals(childElementName, stringComparison))
      {
        childElement = resultElement;
        return true;
      }

      if (child.TryFindVisualChildByName(childElementName, out childElement))
      {
        return true;
      }
    }

    return false;
  }
}

Example

private void VideoComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
  var listView = sender as ListView;
  object item = listView.SelectedItem;
  var itemContainer = listView.ItemContainerGenerator.ContainerFromItem(item) as ListViewItem;

  if (itemContainer.TryFindVisualChildByName("VideoTitleLabel", out Label label))
  {
    var videoTitleText = label.Content as string;
    MessageBox.Show(videoTitleText);
  }
}


问:
Datetime substitution in Apache - Camel Kubernetes Yaml file
I wanted to deploy S3 kafka sink connector (using Apache Camel) in kubernetes using reference document https://ibm-cloud-architecture.github.io/refarch-eda/scenarios/connect-s3/

DateTime placeholder (${date:now:yyyyMMdd-HHmmssSSS} used in this Kubernetes deployment file is not resolved. Whereas the ${file:} is resolved.

```<code>apiVersion: kafka.strimzi.io/v1alpha1
kind: KafkaConnector
metadata:
  name: s3-sink-connector
  labels:
    strimzi.io/cluster: my-connect-cluster
spec:
  class: org.apache.camel.kafkaconnector.CamelSinkConnector
  tasksMax: 1
  config:
    key.converter: org.apache.kafka.connect.storage.StringConverter
    value.converter: org.apache.kafka.connect.storage.StringConverter
    topics: my-replicated-topic
    camel.sink.url: aws-s3://kafka-s3?keyName=s3-connect/${date:now:yyyyMMdd-HHmmssSSS} <-- NOT RESOLVED
    camel.component.aws-s3.configuration.autocloseBody: false
    camel.component.aws-s3.accessKey: ${file:/opt/kafka/external-configuration/aws-credentials/aws-credentials.properties:aws_access_key_id}  <-- RESOLVED
    camel.component.aws-s3.secretKey: ${file:/opt/kafka/external-configuration/aws-credentials/aws-credentials.properties:aws_secret_access_key}  <-- RESOLVED

</code>```

I see both ${date:now:yyyyMMdd} and exchangeId in this document (https://camel.apache.org/components/latest/languages/simple-language.html)

答:
As described in this issue: https://github.com/apache/camel-kafka-connector/issues/251 DateTime placeholders are not supported yet.

They probably will be according to https://github.com/apache/camel-kafka-connector/issues/252.

Body:
I wanted to deploy S3 kafka sink connector (using Apache Camel) in kubernetes using reference document https://ibm-cloud-architecture.github.io/refarch-eda/scenarios/connect-s3/

DateTime placeholder (${date:now:yyyyMMdd-HHmmssSSS} used in this Kubernetes deployment file is not resolved. Whereas the ${file:} is resolved.

apiVersion: kafka.strimzi.io/v1alpha1
kind: KafkaConnector
metadata:
  name: s3-sink-connector
  labels:
    strimzi.io/cluster: my-connect-cluster
spec:
  class: org.apache.camel.kafkaconnector.CamelSinkConnector
  tasksMax: 1
  config:
    key.converter: org.apache.kafka.connect.storage.StringConverter
    value.converter: org.apache.kafka.connect.storage.StringConverter
    topics: my-replicated-topic
    camel.sink.url: aws-s3://kafka-s3?keyName=s3-connect/${date:now:yyyyMMdd-HHmmssSSS} <-- NOT RESOLVED
    camel.component.aws-s3.configuration.autocloseBody: false
    camel.component.aws-s3.accessKey: ${file:/opt/kafka/external-configuration/aws-credentials/aws-credentials.properties:aws_access_key_id}  <-- RESOLVED
    camel.component.aws-s3.secretKey: ${file:/opt/kafka/external-configuration/aws-credentials/aws-credentials.properties:aws_secret_access_key}  <-- RESOLVED

I see both ${date:now:yyyyMMdd} and exchangeId in this document (https://camel.apache.org/components/latest/languages/simple-language.html)


问:
Can any one help me with this one . I was trying to write a prog for finding 'LCM'. I want to equate these variable
Here c and d basically represent tables of respective number for variable a and b...i am trying to match the least common product from these table.Please help me figure it out</p>

```<code>a=(input('your first no: '))
b=(input('your second no: '))

for i in range(1,100):
    c=a*i
    d=b*i
    if (c==d):
    print('lcm is')
</code>```

答:
Use the formula lcm(a,b) = a⋅b / gcd(a,b). Python has a gcd function in the standard library:

```<code>from fractions import gcd

def least_common_multiple(a, b):
    return a * b / gcd(a, b)
</code>```

Since Python 3.6, it's arguably preferable to use the gcd builtin from math:

```<code>try:
    from math import gcd
except ImportError:
    from fractions import gcd

def least_common_multiple(a, b):
    return a * b / gcd(a, b)
</code>```

Body:
Here c and d basically represent tables of respective number for variable a and b...i am trying to match the least common product from these table.Please help me figure it out

a=(input('your first no: '))
b=(input('your second no: '))

for i in range(1,100):
    c=a*i
    d=b*i
    if (c==d):
    print('lcm is')

Body:
Use the formula lcm(a,b) = a⋅b / gcd(a,b). Python has a gcd function in the standard library:

from fractions import gcd

def least_common_multiple(a, b):
    return a * b / gcd(a, b)

Since Python 3.6, it's arguably preferable to use the gcd builtin from math:

try:
    from math import gcd
except ImportError:
    from fractions import gcd

def least_common_multiple(a, b):
    return a * b / gcd(a, b)


问:
Converting to Serializable object
this may be a stupid question but I wanted to convert a 2 dimensional string array into a serializable object in java. What is the best way to do this?</p>

答:
Arrays are already Serializable. So is String. You don't need anything more.

Here is a complete example :

```<code>import java.io.*;
import java.util.Arrays;

/**
 * @author Colin Hebert
 */
public class Serial {

    public static void main(String[] args)
            throws IOException, ClassNotFoundException {
        PipedOutputStream pos = new PipedOutputStream();
        PipedInputStream pis = new PipedInputStream(pos);

        String[][] strings = new String[][]{{"q","w","e"},{"a","s","d"},{"z",
                "x","c"}};

        serialize(strings, pos);

        String[][] strings2 = deserialize(pis);

        System.out.println(Arrays.deepEquals(strings, strings2));
    }

    public static String[][] deserialize(InputStream is)
            throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(is);
        return (String[][]) ois.readObject();
    }

    public static void serialize(String[][] array, OutputStream os)
            throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(os);

        oos.writeObject(array);
        oos.flush();
    }
}
</code>```

Resources:

This code on ideone

oracle.com - Object Serialization Stream Protocol

ContentLicense: CC BY-SA 3.0

Title: Converting to Serializable object

Body:
Arrays are already Serializable. So is String. You don't need anything more.

Here is a complete example :

import java.io.*;
import java.util.Arrays;

/**
 * @author Colin Hebert
 */
public class Serial {

    public static void main(String[] args)
            throws IOException, ClassNotFoundException {
        PipedOutputStream pos = new PipedOutputStream();
        PipedInputStream pis = new PipedInputStream(pos);

        String[][] strings = new String[][]{{"q","w","e"},{"a","s","d"},{"z",
                "x","c"}};

        serialize(strings, pos);

        String[][] strings2 = deserialize(pis);

        System.out.println(Arrays.deepEquals(strings, strings2));
    }

    public static String[][] deserialize(InputStream is)
            throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(is);
        return (String[][]) ois.readObject();
    }

    public static void serialize(String[][] array, OutputStream os)
            throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(os);

        oos.writeObject(array);
        oos.flush();
    }
}

Resources:

This code on ideone

oracle.com - Object Serialization Stream Protocol


问:
How to make the console print something by pressing a key like F2 or F3
UPDATE! I figured out how to find the keys and defined them in my code. The problem is I don't know how to make it so the console prints the selection and it gives u time to press a key. Then it gets plugged into to the switch which prints the current gun depending on the key pressed. I am also using windows 10. I also have encountered another problem I want it to print out Guns first then ask for an input (this part works fine) but then instead of just printing the attachments, it prints out both attachments and the humanized level.</p>

```<code>#include <iostream>
#include <istream>
#include <fstream>
#include <string.h>
#include <conio.h>
#include <string>

using namespace std;

#define KEY_F1 17
#define KEY_F2 18
#define KEY_F3 19
#define KEY_F4 20
#define KEY_F5 21
#define KEY_F6 22
#define KEY_F7 23
#define KEY_F8 24
#define KEY_F9 25
#define KEY_F10 26
#define KEY_F11 27
#define KEY_F12 28

#define KEY_N7 103
#define KEY_N8 104
#define KEY_N9 105

int main() {

    char gun;
    char att;
    char hum;

    char key = _getch();
    int value = key;

    cout << "" << endl;

    cout << "Developed by ! CaptaiN#9999" << endl;

    cout << "" << endl;

    cout << "Guns" << endl;

    cout << "" << endl;

    cout << "[F1]   AK" << endl;
    cout << "[F2]   MP5" << endl;
    cout << "[F3]   M2" << endl;
    cout << "[F4]   SAR" << endl;
    cout << "[F5]   Tommy" << endl;
    cout << "[F6]   Custom" << endl;
    cin >> gun;

    cout << "" << endl;

    cout << "Attachnments" << endl;

    cout << "" << endl;

    cout << "[F7]   Holosight" << endl;
    cout << "[F8]   Simplesight" << endl;
    cout << "[F9]   Silencer" << endl;
    cout << "[F10]  8x Zoom Scope" << endl;
    cout << "[F11]  16x Zoom Scope" << endl;
    cout << "[F12]  No Attachment" << endl;
    cin >> att;

    cout << "" << endl;

    cout << "Humanize Levels" << endl;

    cout << "" << endl;

    cout << "[Numpad 7]  3 (HIGH)" << endl;
    cout << "[Numpad 8]  2 (MODERATE)" << endl;
    cout << "[Numpad 9]  1 (LOW)" << endl;
    cin >> hum;

    //system("CLS");

    while (value != KEY_X) {

        switch (_getch()) {

        case KEY_F1:
            cout << "Current Gun: AK" << endl;
            break;
        case KEY_F2:
            cout << "Current Gun: MP5" << endl;
            break;
        case KEY_F3:
            cout << "Current Gun: M2" << endl;
            break;
        case KEY_F4:
            cout << "Current Gun: SAR" << endl;
            break;
        case KEY_F5:
            cout << "Current Gun: Tommy" << endl;
            break;
        case KEY_F6:
            cout << "Current Gun: Custom" << endl;
            break;
        }

        switch (att) {

        case KEY_F7:
            cout << "Current Attachment: Holosight" << endl;
            break;
        case KEY_F8:
            cout << "Current Attachment: Simplesight" << endl;
            break;
        case KEY_F9:
            cout << "Current Attachment: Silencer" << endl;
            break;
        case KEY_F10:
            cout << "Current Attachment: 8x Zoom Scope" << endl;
            break;
        case KEY_F11:
            cout << "Current Attachment: 16x Zoom Scope" << endl;
            break;
        case KEY_F12:
            cout << "Current Attachment: None" << endl;
            break;
        }

        switch (hum) {

        case KEY_N7:
            cout << "Humanized Level: 3" << endl;
            break;
        case KEY_N8:
            cout << "Humanized Level: 2" << endl;
            break;
        case KEY_N9:
            cout << "Humanized Level: 1" << endl;
            break;
        }
    }
}
</code>```

答:
Okay, so since your question has basically changed, I'll put a new answer to address it. I see you've gone with the platform-specific option. Luckily, I'm on Windows 10 as well, so I can still help.

First things first, I'm having some difficulty with the keycodes you listed in your defines - I'm getting a null character (0) and then some other character like ; (59) for F1 and > (60) for F2. For F11 and F12 I get a completely different set of characters (as you can see in my code). I'm not really sure why we'd be getting different results, maybe something weird with encodings? Would you mind stating where you found the character codes listed in the snippet? For the rest of my answer, I'll just use what I'm getting (sorry, I don't know what else to do).

Here is the code that will achieve what I think you want - it gets the user's initial "loadout" in the first part of the code. In the main loop it allows you to enter a new weapon, and just prints the attachment selected earlier. I didn't add handling for the number pad keys, but the technique should be the same if you want to do it.

#include <iostream>
#include <string>
#include <conio.h>
#include <array>
#include <map>

// define the parts for all F* keys
using multipart_t = std::array<int, 2>;
constexpr multipart_t KEY_F1 = { 0, 59 };
constexpr multipart_t KEY_F2{ 0, 60 };
constexpr multipart_t KEY_F3{ 0, 61 };
constexpr multipart_t KEY_F4{ 0, 62 };
constexpr multipart_t KEY_F5{ 0, 63 };
constexpr multipart_t KEY_F6{ 0, 64 };
constexpr multipart_t KEY_F7{ 0, 65 };
constexpr multipart_t KEY_F8{ 0, 66 };
constexpr multipart_t KEY_F9{ 0, 67 };
constexpr multipart_t KEY_F10{ 0, 68 };
constexpr multipart_t KEY_F11 = { 224, 133 };
constexpr multipart_t KEY_F12 = { 224, 134 };

// map those arrays to the corresponding ints
const std::map<multipart_t, int> F_KEY_TO_INT{
    { KEY_F1, 1 },
    { KEY_F2, 2 },
    { KEY_F3, 3 },
    { KEY_F4, 4 },
    { KEY_F5, 5 },
    { KEY_F6, 6 },
    { KEY_F7, 7 },
    { KEY_F8, 8 },
    { KEY_F9, 9 },
    { KEY_F10, 10 },
    { KEY_F11, 11 },
    { KEY_F12, 12 }
};

// add a utility function that returns the pressed key as an int of 1-12 (for F1-F12 keys)
int fGetch() {
    // TODO: add checking to check it actually is an F* key instead of just failing silently (REALLY BAD)
    multipart_t keys;
    keys[0] = _getch();
    keys[1] = _getch();
    return F_KEY_TO_INT.find(keys)->second;
}

int main() {
    std::cout << "" << '\n';

    std::cout << "Developed by ! CaptaiN#9999" << '\n';

    std::cout << "" << '\n';

    std::cout << "Guns" << '\n';

    std::cout << "" << '\n';

    std::cout << "[F1]   AK" << '\n';
    std::cout << "[F2]   MP5" << '\n';
    std::cout << "[F3]   M2" << '\n';
    std::cout << "[F4]   SAR" << '\n';
    std::cout << "[F5]   Tommy" << '\n';
    std::cout << "[F6]   Custom" << '\n';
    // TODO: valid character checking (for all 3)
    int gun(fGetch());

    std::cout << "" << '\n';

    std::cout << "Attachnments" << '\n';

    std::cout << "" << '\n';

    std::cout << "[F7]   Holosight" << '\n';
    std::cout << "[F8]   Simplesight" << '\n';
    std::cout << "[F9]   Silencer" << '\n';
    std::cout << "[F10]  8x Zoom Scope" << '\n';
    std::cout << "[F11]  16x Zoom Scope" << '\n';
    std::cout << "[F12]  No Attachment" << '\n';
    int att(fGetch());

    // I'll leave you to handle function keys, it should be basically the same
    /*std::cout << "" << '\n';

    std::cout << "Humanize Levels" << '\n';

    std::cout << "" << '\n';

    std::cout << "[Numpad 7]  3 (HIGH)" << '\n';
    std::cout << "[Numpad 8]  2 (MODERATE)" << '\n';
    std::cout << "[Numpad 9]  1 (LOW)" << '\n';
    std::cin >> hum;*/

    system("CLS");

    std::cout << "main loop start" << '\n';
    int value = 0;
    while (value != 'x') {
        value = fGetch();

        switch (value) {
        case 1:
            std::cout << "Current Gun: AK" << '\n';
            break;
        case 2:
            std::cout << "Current Gun: MP5" << '\n';
            break;
        case 3:
            std::cout << "Current Gun: M2" << '\n';
            break;
        case 4:
            std::cout << "Current Gun: SAR" << '\n';
            break;
        case 5:
            std::cout << "Current Gun: Tommy" << '\n';
            break;
        case 6:
            std::cout << "Current Gun: Custom" << '\n';
            break;
        }

        switch (att) {

        case 7:
            std::cout << "Current Attachment: Holosight" << '\n';
            break;
        case 8:
            std::cout << "Current Attachment: Simplesight" << '\n';
            break;
        case 9:
            std::cout << "Current Attachment: Silencer" << '\n';
            break;
        case 10:
            std::cout << "Current Attachment: 8x Zoom Scope" << '\n';
            break;
        case 1:
            std::cout << "Current Attachment: 16x Zoom Scope" << '\n';
            break;
        case 12:
            std::cout << "Current Attachment: None" << '\n';
            break;
        }

        // TODO
        /*switch (hum) {

        case KEY_N7:
            std::cout << "Humanized Level: 3" << '\n';
            break;
        case KEY_N8:
            std::cout << "Humanized Level: 2" << '\n';
            break;
        case KEY_N9:
            std::cout << "Humanized Level: 1" << '\n';
            break;
        }*/
    }
}
```

In the code, I've added places for you to improve upon mine (it's mostly checking for a user typing the wrong key at the wrong time).

The actual input was handled by putting the multiple characters into an array and using a map to map that to the appropriate int for that F1-F12 key. Please note that the function currently has next to no error checking.

Body:
UPDATE! I figured out how to find the keys and defined them in my code. The problem is I don't know how to make it so the console prints the selection and it gives u time to press a key. Then it gets plugged into to the switch which prints the current gun depending on the key pressed. I am also using windows 10. I also have encountered another problem I want it to print out Guns first then ask for an input (this part works fine) but then instead of just printing the attachments, it prints out both attachments and the humanized level.

#include <iostream>
#include <istream>
#include <fstream>
#include <string.h>
#include <conio.h>
#include <string>

using namespace std;

#define KEY_F1 17
#define KEY_F2 18
#define KEY_F3 19
#define KEY_F4 20
#define KEY_F5 21
#define KEY_F6 22
#define KEY_F7 23
#define KEY_F8 24
#define KEY_F9 25
#define KEY_F10 26
#define KEY_F11 27
#define KEY_F12 28

#define KEY_N7 103
#define KEY_N8 104
#define KEY_N9 105

int main() {

    char gun;
    char att;
    char hum;

    char key = _getch();
    int value = key;

    cout << "" << endl;

    cout << "Developed by ! CaptaiN#9999" << endl;

    cout << "" << endl;

    cout << "Guns" << endl;

    cout << "" << endl;

    cout << "[F1]   AK" << endl;
    cout << "[F2]   MP5" << endl;
    cout << "[F3]   M2" << endl;
    cout << "[F4]   SAR" << endl;
    cout << "[F5]   Tommy" << endl;
    cout << "[F6]   Custom" << endl;
    cin >> gun;

    cout << "" << endl;

    cout << "Attachnments" << endl;

    cout << "" << endl;

    cout << "[F7]   Holosight" << endl;
    cout << "[F8]   Simplesight" << endl;
    cout << "[F9]   Silencer" << endl;
    cout << "[F10]  8x Zoom Scope" << endl;
    cout << "[F11]  16x Zoom Scope" << endl;
    cout << "[F12]  No Attachment" << endl;
    cin >> att;

    cout << "" << endl;

    cout << "Humanize Levels" << endl;

    cout << "" << endl;

    cout << "[Numpad 7]  3 (HIGH)" << endl;
    cout << "[Numpad 8]  2 (MODERATE)" << endl;
    cout << "[Numpad 9]  1 (LOW)" << endl;
    cin >> hum;

    //system("CLS");

    while (value != KEY_X) {

        switch (_getch()) {

        case KEY_F1:
            cout << "Current Gun: AK" << endl;
            break;
        case KEY_F2:
            cout << "Current Gun: MP5" << endl;
            break;
        case KEY_F3:
            cout << "Current Gun: M2" << endl;
            break;
        case KEY_F4:
            cout << "Current Gun: SAR" << endl;
            break;
        case KEY_F5:
            cout << "Current Gun: Tommy" << endl;
            break;
        case KEY_F6:
            cout << "Current Gun: Custom" << endl;
            break;
        }

        switch (att) {

        case KEY_F7:
            cout << "Current Attachment: Holosight" << endl;
            break;
        case KEY_F8:
            cout << "Current Attachment: Simplesight" << endl;
            break;
        case KEY_F9:
            cout << "Current Attachment: Silencer" << endl;
            break;
        case KEY_F10:
            cout << "Current Attachment: 8x Zoom Scope" << endl;
            break;
        case KEY_F11:
            cout << "Current Attachment: 16x Zoom Scope" << endl;
            break;
        case KEY_F12:
            cout << "Current Attachment: None" << endl;
            break;
        }

        switch (hum) {

        case KEY_N7:
            cout << "Humanized Level: 3" << endl;
            break;
        case KEY_N8:
            cout << "Humanized Level: 2" << endl;
            break;
        case KEY_N9:
            cout << "Humanized Level: 1" << endl;
            break;
        }
    }
}

Body:
Okay, so since your question has basically changed, I'll put a new answer to address it. I see you've gone with the platform-specific option. Luckily, I'm on Windows 10 as well, so I can still help.

First things first, I'm having some difficulty with the keycodes you listed in your defines - I'm getting a null character (0) and then some other character like ; (59) for F1 and > (60) for F2. For F11 and F12 I get a completely different set of characters (as you can see in my code). I'm not really sure why we'd be getting different results, maybe something weird with encodings? Would you mind stating where you found the character codes listed in the snippet? For the rest of my answer, I'll just use what I'm getting (sorry, I don't know what else to do).

Here is the code that will achieve what I think you want - it gets the user's initial "loadout" in the first part of the code. In the main loop it allows you to enter a new weapon, and just prints the attachment selected earlier. I didn't add handling for the number pad keys, but the technique should be the same if you want to do it.

#include <iostream>
#include <string>
#include <conio.h>
#include <array>
#include <map>

// define the parts for all F* keys
using multipart_t = std::array<int, 2>;
constexpr multipart_t KEY_F1 = { 0, 59 };
constexpr multipart_t KEY_F2{ 0, 60 };
constexpr multipart_t KEY_F3{ 0, 61 };
constexpr multipart_t KEY_F4{ 0, 62 };
constexpr multipart_t KEY_F5{ 0, 63 };
constexpr multipart_t KEY_F6{ 0, 64 };
constexpr multipart_t KEY_F7{ 0, 65 };
constexpr multipart_t KEY_F8{ 0, 66 };
constexpr multipart_t KEY_F9{ 0, 67 };
constexpr multipart_t KEY_F10{ 0, 68 };
constexpr multipart_t KEY_F11 = { 224, 133 };
constexpr multipart_t KEY_F12 = { 224, 134 };

// map those arrays to the corresponding ints
const std::map<multipart_t, int> F_KEY_TO_INT{
    { KEY_F1, 1 },
    { KEY_F2, 2 },
    { KEY_F3, 3 },
    { KEY_F4, 4 },
    { KEY_F5, 5 },
    { KEY_F6, 6 },
    { KEY_F7, 7 },
    { KEY_F8, 8 },
    { KEY_F9, 9 },
    { KEY_F10, 10 },
    { KEY_F11, 11 },
    { KEY_F12, 12 }
};

// add a utility function that returns the pressed key as an int of 1-12 (for F1-F12 keys)
int fGetch() {
    // TODO: add checking to check it actually is an F* key instead of just failing silently (REALLY BAD)
    multipart_t keys;
    keys[0] = _getch();
    keys[1] = _getch();
    return F_KEY_TO_INT.find(keys)->second;
}

int main() {
    std::cout << "" << '\n';

    std::cout << "Developed by ! CaptaiN#9999" << '\n';

    std::cout << "" << '\n';

    std::cout << "Guns" << '\n';

    std::cout << "" << '\n';

    std::cout << "[F1]   AK" << '\n';
    std::cout << "[F2]   MP5" << '\n';
    std::cout << "[F3]   M2" << '\n';
    std::cout << "[F4]   SAR" << '\n';
    std::cout << "[F5]   Tommy" << '\n';
    std::cout << "[F6]   Custom" << '\n';
    // TODO: valid character checking (for all 3)
    int gun(fGetch());

    std::cout << "" << '\n';

    std::cout << "Attachnments" << '\n';

    std::cout << "" << '\n';

    std::cout << "[F7]   Holosight" << '\n';
    std::cout << "[F8]   Simplesight" << '\n';
    std::cout << "[F9]   Silencer" << '\n';
    std::cout << "[F10]  8x Zoom Scope" << '\n';
    std::cout << "[F11]  16x Zoom Scope" << '\n';
    std::cout << "[F12]  No Attachment" << '\n';
    int att(fGetch());

    // I'll leave you to handle function keys, it should be basically the same
    /*std::cout << "" << '\n';

    std::cout << "Humanize Levels" << '\n';

    std::cout << "" << '\n';

    std::cout << "[Numpad 7]  3 (HIGH)" << '\n';
    std::cout << "[Numpad 8]  2 (MODERATE)" << '\n';
    std::cout << "[Numpad 9]  1 (LOW)" << '\n';
    std::cin >> hum;*/

    system("CLS");

    std::cout << "main loop start" << '\n';
    int value = 0;
    while (value != 'x') {
        value = fGetch();

        switch (value) {
        case 1:
            std::cout << "Current Gun: AK" << '\n';
            break;
        case 2:
            std::cout << "Current Gun: MP5" << '\n';
            break;
        case 3:
            std::cout << "Current Gun: M2" << '\n';
            break;
        case 4:
            std::cout << "Current Gun: SAR" << '\n';
            break;
        case 5:
            std::cout << "Current Gun: Tommy" << '\n';
            break;
        case 6:
            std::cout << "Current Gun: Custom" << '\n';
            break;
        }

        switch (att) {

        case 7:
            std::cout << "Current Attachment: Holosight" << '\n';
            break;
        case 8:
            std::cout << "Current Attachment: Simplesight" << '\n';
            break;
        case 9:
            std::cout << "Current Attachment: Silencer" << '\n';
            break;
        case 10:
            std::cout << "Current Attachment: 8x Zoom Scope" << '\n';
            break;
        case 1:
            std::cout << "Current Attachment: 16x Zoom Scope" << '\n';
            break;
        case 12:
            std::cout << "Current Attachment: None" << '\n';
            break;
        }

        // TODO
        /*switch (hum) {

        case KEY_N7:
            std::cout << "Humanized Level: 3" << '\n';
            break;
        case KEY_N8:
            std::cout << "Humanized Level: 2" << '\n';
            break;
        case KEY_N9:
            std::cout << "Humanized Level: 1" << '\n';
            break;
        }*/
    }
}

In the code, I've added places for you to improve upon mine (it's mostly checking for a user typing the wrong key at the wrong time).

The actual input was handled by putting the multiple characters into an array and using a map to map that to the appropriate int for that F1-F12 key. Please note that the function currently has next to no error checking.


问:
How to run Azure Function app on a different port in Visual Studio
I am setting local host port in local.setting.json. Referring Microsoft doc https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local

The file looks like below

```<code>{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "AzureWebJobsDashboard": ""
  },
  "Host": {
    "LocalHttpPort": 7073
  }
}
</code>```

When I run/debug the solution , VS still host the app on default port (7071)

I have checked the bin directory, the local.setting.json file is geting there with above settings.
Running Azure Fucntion CLI (func host start) from bin directory correctly read the port number.

Looks like VS is not using the "LocalHttpPort" port. Is there any other changes required in the settings. I have Visual Studio 2017 Preview (2)

答:
To do this

Select the Function App Project in Visual Studio -> Hit Alt+Enter and navigate to Debug settings and set

```<code>host start --port 8085 --nodeDebugPort 6890
</code>```

Body:
I am setting local host port in local.setting.json. Referring Microsoft doc https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local

The file looks like below

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "AzureWebJobsDashboard": ""
  },
  "Host": {
    "LocalHttpPort": 7073
  }
}

When I run/debug the solution , VS still host the app on default port (7071)

I have checked the bin directory, the local.setting.json file is geting there with above settings.
Running Azure Fucntion CLI (func host start) from bin directory correctly read the port number.

Looks like VS is not using the "LocalHttpPort" port. Is there any other changes required in the settings. I have Visual Studio 2017 Preview (2)

Body:
To do this

Select the Function App Project in Visual Studio -> Hit Alt+Enter and navigate to Debug settings and set

host start --port 8085 --nodeDebugPort 6890


问:
C++ Bad access when assigning an element to map value
So the question explains the problem...

Background:

I'm trying to solve this problem from HackerRank.

It's basically an html tag parser. Valid input guaranteed, attributes are strings only.

My Approach

I created a custom Tag class that can store a map<string,Tag> of other Tag's, as well as a map<string,string> of attributes. The parsing seems to be working correctly.

The Problem

During the querying part, I get a BAD_ACCESS error on the following query/html combo:

```<code>4 1
<a value = "GoodVal">
<b value = "BadVal" size = "10">
</b>
</a>
a.b~size
</code>```

The error occurs when I try to access the b Tag from a. Specifically, it's in the t=t.tags[tag_name], Line 118 below.

Code

```<code>#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <stack>
using namespace std;

class Tag {
public:
    Tag(){};
    Tag(string name):name(name){};
    string name;
    map<string,Tag> tags = map<string, Tag>();
    map<string,string> attribs=map<string,string>();
};

int main() {
    int lines, queries;
    std::cin>>lines>>queries;

    std:string str;
    getline(cin, str);
    stack<string> open;
    auto tags = map<string, Tag>();
    for (int i = 0; i < lines; i++) {
        getline(cin, str);
        if (str.length()>1){
            // If it's not </tag>, then it's an opening tag
            if  (str[1] != '/') {
                // Parse tag name
                auto wordidx = str.find(" ");
                if (wordidx == -1) {
                    wordidx = str.length()-1.f;
                }
                string name = str.substr(1,wordidx-1);
                auto t = Tag(name);

                string sub = str.substr(wordidx);
                auto equalidx=sub.find("=");

                // Parse Attributes
                while (equalidx != std::string::npos) {
                    string key = sub.substr(1,equalidx-2);
                    sub = sub.substr(equalidx);
                    auto attrib_start = sub.find("\"");
                    sub = sub.substr(attrib_start+1);
                    auto attrib_end = sub.find("\"");
                    string val = sub.substr(0, attrib_end);
                    sub = sub.substr(attrib_end+1);

                    t.attribs[key] = val;
                    equalidx=sub.find("=");
                }

                // If we're in a tag, push to that, else push to the base tags
                if (open.size() == 0) {
                    tags[name] = t;
                } else {
                    tags[open.top()].tags[name]=t;
                }
                open.push(name);
            } else {
                // Pop the stack if we reached a closing tag
                auto wordidx = str.find(">");
                string name = str.substr(2,wordidx-2);

                // Sanity check, but we're assuming valid input
                if (name.compare(open.top())) {
                    cout<<"FUCK"<<name<<open.top()<<endl;
                    return 9;
                }
                open.pop();
            }

        } else {
            std::cout<<"FUCK\n";
        }
    }

    //
    // Parse in queries
    //
    for (int i = 0; i < queries; i++) {
        getline(cin, str);
        Tag t = Tag();
        bool defined = false;

        auto next_dot = str.find(".");
        while (next_dot!=string::npos) {
            string name = str.substr(0,next_dot);
            if (defined && t.tags.find(name) == t.tags.end()) {
                //TAG NOT IN T
                cout<<"Not Found!"<<endl;
                continue;
            }
            t = !defined ? tags[name] : t.tags[name];
            defined = true;

            str = str.substr(next_dot+1);
            next_dot = str.find(".");
        }

        auto splitter = str.find("~");
        string tag_name = str.substr(0,splitter);
        string attrib_name = str.substr(splitter+1);

        if (!defined) {
            t = tags[tag_name];
        } else if (t.tags.find(tag_name) == t.tags.end()) {
            //TAG NOT IN T
            cout<<"Not Found!"<<endl;
            continue;
        } else {
            t = t.tags[tag_name];
        }
        // T is now set, check the attribute
        if (t.attribs.find(attrib_name) == t.attribs.end()) {
            cout<<"Not Found!"<<endl;
        } else {
            cout<<t.attribs[attrib_name]<<endl;
        }

    }

    return 0;
}

</code>```

What I've tried

This is fixed by just defining Tag x = t.tags[tag_name]; in the line above as a new variable, and then doing t = x; but why is this even happening?

Also, the following query also then fails: a.b.c~height, but it fails on Line 99 when it tried to get a.tags["b"]. No idea why. I was gonna just go with the hacky fix above, but this seems like a big core issue that i'm doing wrong.

I would suggest running this on an IDE and verifying that the parsing is indeed correct.

答:
```<code>t=t.tags[tag_name]
</code>```

This expression is unsafe because you are copy-assigning an object that is owned by that object over the owning object.

Consider what happens on this line:

The map lookup is performed and returns a Tag&.

You try to copy-assign this to t, invoking the implicit copy-assigment operator.

This operator copy-assigns t.tags from the tags attribute of the copy source -- which lives in t.tags.

The result is that the object you're copying into t is destroyed in the middle of that copy.  This causes undefined behavior, and an immediate crash is honestly the best possible outcome as it told you exactly where the problem was.  (This kind of problem frequently manifests at some point later in the program, at which point you've lost the state necessary to figure out what caused the UB.)

One workaround would be to move the source object into a temporary and then move-assign that temporary over t:

```<code>t = Tag{std::move(t.tags[tag_name])};
</code>```

This lifts the data we want to assign to t out of t before we try to put it in t.  Then, when t's assignment operator goes to replace t.tags, the data you're trying to assign to t doesn't live there anymore.

However, this overall approach involves a lot of unnecessary copying. It would be better to declare t as Tag const *t; instead -- have it be a pointer to a tag.  Then you can just move that pointer around to point at other tags in your data structure without making copies.

Side note: I just did this problem the other day!  Here's a hint that might help you simplify things: do you actually need a structure of tags?  Is there a simpler type of lookup structure that would work instead of nested tags?

Body:
So the question explains the problem...

Background:

I'm trying to solve this problem from HackerRank.

It's basically an html tag parser. Valid input guaranteed, attributes are strings only.

My Approach

I created a custom Tag class that can store a map<string,Tag> of other Tag's, as well as a map<string,string> of attributes. The parsing seems to be working correctly.

The Problem

During the querying part, I get a BAD_ACCESS error on the following query/html combo:

4 1

a.b~size

The error occurs when I try to access the b Tag from a. Specifically, it's in the t=t.tags[tag_name], Line 118 below.

Code

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <map>
#include <stack>
using namespace std;

class Tag {
public:
    Tag(){};
    Tag(string name):name(name){};
    string name;
    map<string,Tag> tags = map<string, Tag>();
    map<string,string> attribs=map<string,string>();
};

int main() {
    int lines, queries;
    std::cin>>lines>>queries;

    std:string str;
    getline(cin, str);
    stack<string> open;
    auto tags = map<string, Tag>();
    for (int i = 0; i < lines; i++) {
        getline(cin, str);
        if (str.length()>1){
            // If it's not </tag>, then it's an opening tag
            if  (str[1] != '/') {
                // Parse tag name
                auto wordidx = str.find(" ");
                if (wordidx == -1) {
                    wordidx = str.length()-1.f;
                }
                string name = str.substr(1,wordidx-1);
                auto t = Tag(name);

                string sub = str.substr(wordidx);
                auto equalidx=sub.find("=");

                // Parse Attributes
                while (equalidx != std::string::npos) {
                    string key = sub.substr(1,equalidx-2);
                    sub = sub.substr(equalidx);
                    auto attrib_start = sub.find("\"");
                    sub = sub.substr(attrib_start+1);
                    auto attrib_end = sub.find("\"");
                    string val = sub.substr(0, attrib_end);
                    sub = sub.substr(attrib_end+1);

                    t.attribs[key] = val;
                    equalidx=sub.find("=");
                }

                // If we're in a tag, push to that, else push to the base tags
                if (open.size() == 0) {
                    tags[name] = t;
                } else {
                    tags[open.top()].tags[name]=t;
                }
                open.push(name);
            } else {
                // Pop the stack if we reached a closing tag
                auto wordidx = str.find(">");
                string name = str.substr(2,wordidx-2);

                // Sanity check, but we're assuming valid input
                if (name.compare(open.top())) {
                    cout<<"FUCK"<<name<<open.top()<<endl;
                    return 9;
                }
                open.pop();
            }

        } else {
            std::cout<<"FUCK\n";
        }
    }

    //
    // Parse in queries
    //
    for (int i = 0; i < queries; i++) {
        getline(cin, str);
        Tag t = Tag();
        bool defined = false;

        auto next_dot = str.find(".");
        while (next_dot!=string::npos) {
            string name = str.substr(0,next_dot);
            if (defined && t.tags.find(name) == t.tags.end()) {
                //TAG NOT IN T
                cout<<"Not Found!"<<endl;
                continue;
            }
            t = !defined ? tags[name] : t.tags[name];
            defined = true;

            str = str.substr(next_dot+1);
            next_dot = str.find(".");
        }

        auto splitter = str.find("~");
        string tag_name = str.substr(0,splitter);
        string attrib_name = str.substr(splitter+1);

        if (!defined) {
            t = tags[tag_name];
        } else if (t.tags.find(tag_name) == t.tags.end()) {
            //TAG NOT IN T
            cout<<"Not Found!"<<endl;
            continue;
        } else {
            t = t.tags[tag_name];
        }
        // T is now set, check the attribute
        if (t.attribs.find(attrib_name) == t.attribs.end()) {
            cout<<"Not Found!"<<endl;
        } else {
            cout<<t.attribs[attrib_name]<<endl;
        }

    }

    return 0;
}

What I've tried

This is fixed by just defining Tag x = t.tags[tag_name]; in the line above as a new variable, and then doing t = x; but why is this even happening?

Also, the following query also then fails: a.b.c~height, but it fails on Line 99 when it tried to get a.tags["b"]. No idea why. I was gonna just go with the hacky fix above, but this seems like a big core issue that i'm doing wrong.

I would suggest running this on an IDE and verifying that the parsing is indeed correct.

Body:
t=t.tags[tag_name]

This expression is unsafe because you are copy-assigning an object that is owned by that object over the owning object.

Consider what happens on this line:

The map lookup is performed and returns a Tag&.

You try to copy-assign this to t, invoking the implicit copy-assigment operator.

This operator copy-assigns t.tags from the tags attribute of the copy source -- which lives in t.tags.

The result is that the object you're copying into t is destroyed in the middle of that copy.  This causes undefined behavior, and an immediate crash is honestly the best possible outcome as it told you exactly where the problem was.  (This kind of problem frequently manifests at some point later in the program, at which point you've lost the state necessary to figure out what caused the UB.)

One workaround would be to move the source object into a temporary and then move-assign that temporary over t:

t = Tag{std::move(t.tags[tag_name])};

This lifts the data we want to assign to t out of t before we try to put it in t.  Then, when t's assignment operator goes to replace t.tags, the data you're trying to assign to t doesn't live there anymore.

However, this overall approach involves a lot of unnecessary copying. It would be better to declare t as Tag const *t; instead -- have it be a pointer to a tag.  Then you can just move that pointer around to point at other tags in your data structure without making copies.

Side note: I just did this problem the other day!  Here's a hint that might help you simplify things: do you actually need a structure of tags?  Is there a simpler type of lookup structure that would work instead of nested tags?


问:
Best practice for using Django templates and connect it to database
I am trying to build a database for my website. There are currently three entries with different attributes in my database. I have not created these entries in order, but I have assigned a 'Chapter number' attribute which indicates the order 1,2,3.

I am now trying to inject this using 'context' and 'render' function in my views. I am using the method 'objects.all()' to add all objects to my context. I have a simple Html file where I am inserting the data from the database by looping over (a simple for loop) these added objects.

Now the output that is being generated (naturally) is that it is following the order in which I created the database. I am not sure how I can have the loop run in such a way that I get these chapters in correct order. Thank you for patiently reading my question. Any help will be appreciated.

答:
You may use the order_by method which is included in Djangos QuerySet API:

https://docs.djangoproject.com/en/3.0/ref/models/querysets/

If you offer some more information of your specific data I might provide you with an example.

For orientation purposes, sorting queried objects by date would work as follows:

```<code>most_recent = Entry.objects.order_by('-timestamp')
</code>```

You can sort by any field like so:

```<code>sorted_by_field = Entry.objects.order_by('custom_field')
</code>```

Body:
You may use the order_by method which is included in Djangos QuerySet API:

https://docs.djangoproject.com/en/3.0/ref/models/querysets/

If you offer some more information of your specific data I might provide you with an example.

For orientation purposes, sorting queried objects by date would work as follows:

most_recent = Entry.objects.order_by('-timestamp')

You can sort by any field like so:

sorted_by_field = Entry.objects.order_by('custom_field')


问:
What is the "right" way to avoid Aliasing (e.g. when adding an element of a container to itself) in C++?
```<code>std::vector<int> a;
a.push_back(1);
a.push_back(a[0]);
</code>```

I just learned that the code above can be very dangerous.

(If it's not obvious why, you're not alone... it wasn't obvious to me either.)

My questions:

What is the "standard" way of dealing with it? Making a new variable and then assigning it immediately to something afterward seems a bit weird to me. Is there a better way of dealing with it?

How do you train yourself to watch out for aliasing issues like this? What pattern(s) do you look for? I have no idea to recognize this situation; I only learned about aliasing when I learned about the restrict keyword in C, and only now do I understand what the issue really is.

Edit:

I'd love to accept an answer, but it doesn't seem like part (2) of the question has been answered. I'm wondering what strategies people use to locate aliasing mistakes in code they have written.

One strategy I've come up with so far is to avoid passing in the same value for in two parameters. (In this case, one parameter is implicit and one explicit.)

Are there any other easy things to notice and watch out for?

答:
EDIT: Technically, the standard does not mandate that this is correct if the contained type has a no-throw copy constructor. I don't know any implementation where this does not hold anyway, as it would require producing two implementations of push_back when the generic one is just as efficient in all cases.

Aliasing is a problem in general, but not in this particular case. The code:

```<code>assert( v.size() > 0 );
v.push_back( v[0] );
</code>```

Is guaranteed to be correct by the standard (C++03) through the exception guarantees (which are a really good reason not to implement your own containers, you will probably not get them right). In particular §23.1 [lib.container.requirements] / 10 dictattes:

Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) [NOTE: both those references refer to insert on deque and vector respectively] all container types defined in this clause meet the following additional requirements:

— if an exception is thrown by a push_back() or push_front() function, that function has no effects.

Where the important bit is that if any exception is thrown in the operation, the container is left untouched, and that means that no iterator gets invalidated, which in turns means that the original region of memory is left untouched until it is guaranteed that no exceptions will be thrown (with the exception pun intended, of destructors). Because in general copy constructors can throw, the implementation must ensure that all copies are performed before destroying any object.

This becomes more evident in C++0x, when objects are not copied from one location to another, but rather moved. Because the copy of the new element might throw, it has to be performed before any of the moves are executed, or else you would be left in a situation where some of the objects in the original container have been invalidated.

Body:
std::vector<int> a;
a.push_back(1);
a.push_back(a[0]);

I just learned that the code above can be very dangerous.

(If it's not obvious why, you're not alone... it wasn't obvious to me either.)

My questions:

What is the "standard" way of dealing with it? Making a new variable and then assigning it immediately to something afterward seems a bit weird to me. Is there a better way of dealing with it?

How do you train yourself to watch out for aliasing issues like this? What pattern(s) do you look for? I have no idea to recognize this situation; I only learned about aliasing when I learned about the restrict keyword in C, and only now do I understand what the issue really is.

Edit:

I'd love to accept an answer, but it doesn't seem like part (2) of the question has been answered. I'm wondering what strategies people use to locate aliasing mistakes in code they have written.

One strategy I've come up with so far is to avoid passing in the same value for in two parameters. (In this case, one parameter is implicit and one explicit.)

Are there any other easy things to notice and watch out for?

Body:
EDIT: Technically, the standard does not mandate that this is correct if the contained type has a no-throw copy constructor. I don't know any implementation where this does not hold anyway, as it would require producing two implementations of push_back when the generic one is just as efficient in all cases.

Aliasing is a problem in general, but not in this particular case. The code:

assert( v.size() > 0 );
v.push_back( v[0] );

Is guaranteed to be correct by the standard (C++03) through the exception guarantees (which are a really good reason not to implement your own containers, you will probably not get them right). In particular §23.1 [lib.container.requirements] / 10 dictattes:

Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) [NOTE: both those references refer to insert on deque and vector respectively] all container types defined in this clause meet the following additional requirements:

— if an exception is thrown by a push_back() or push_front() function, that function has no effects.

Where the important bit is that if any exception is thrown in the operation, the container is left untouched, and that means that no iterator gets invalidated, which in turns means that the original region of memory is left untouched until it is guaranteed that no exceptions will be thrown (with the exception pun intended, of destructors). Because in general copy constructors can throw, the implementation must ensure that all copies are performed before destroying any object.

This becomes more evident in C++0x, when objects are not copied from one location to another, but rather moved. Because the copy of the new element might throw, it has to be performed before any of the moves are executed, or else you would be left in a situation where some of the objects in the original container have been invalidated.


问:
How to replace characters by strtok function - C?
I really want to change all spaces ' ' in my char array for NULL -

```<code>#include <string.h>

void ReplaceCharactersInString(char *pcString, char *cOldChar, char *cNewChar) {
    char *p = strtok(pcString, cOldChar);
    strcpy(pcString, p);
    while (p != NULL) {
        strcat(pcString, p);
        p = strtok(cNewChar, cOldChar);
    }
}

int main() {
    char pcString[] = "I am testing";
    ReplaceCharactersInString(pcString, " ", NULL);
    printf(pcString);
}
</code>```

OUTPUT: Iamtesting

If I simply put the printf(p) function before:

```<code>p = strtok(cNewChar, cOldChar);
</code>```

In the result I  have what I need - but the problem is how to store it in pcString (directly)?

Or there is maybe a better solution to simply do it?

答:
You want to split the string into individual tokens separated by spaces such as "I\0am\0testing\0". You can use strtok() for this but this function is error prone. I suggest you allocate an array of pointers and make them point to the words. Note that splitting the source string is sloppy and does not allow for tokens to be adjacent such as in 1+1. You could allocate the strings instead.

Here is an example:

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

char **split_string(const char *str, char *delim) {
    size_t i, len, count;
    const char *p;

    /* count tokens */
    p = str;
    p += strspn(p, delim);      // skip initial delimiters
    count = 0;
    while (*p) {
        count++;
        p += strcspn(p, delim); // skip token
        p += strspn(p, delim);  // skip delimiters
    }

    /* allocate token array */
    char **array = calloc(sizeof(*array, count + 1);
    p = str;
    p += strspn(p, delim);      // skip initial delimiters
    for (i = 0; i < count; i++) {
        len = strcspn(p, delim); // token length
        array[i] = strndup(p, len); // allocate a copy of the token
        p += len;               // skip token
        p += strspn(p, delim);  // skip delimiters
    }
    /* array ends with a null pointer */
    array[count] = NULL;
    return array;
}

int main() {
    const char *pcString = "I am testing";
    char **array = split_string(pcString, " \t\r\n");
    for (size_t i = 0; array[i] != NULL; i++) {
        printf("%zu: %s\n", i, array[i]);
    }
    return 0;
}
</code>```

Body:
I really want to change all spaces ' ' in my char array for NULL -

#include <string.h>

void ReplaceCharactersInString(char *pcString, char *cOldChar, char *cNewChar) {
    char *p = strtok(pcString, cOldChar);
    strcpy(pcString, p);
    while (p != NULL) {
        strcat(pcString, p);
        p = strtok(cNewChar, cOldChar);
    }
}

int main() {
    char pcString[] = "I am testing";
    ReplaceCharactersInString(pcString, " ", NULL);
    printf(pcString);
}

OUTPUT: Iamtesting

If I simply put the printf(p) function before:

p = strtok(cNewChar, cOldChar);

In the result I  have what I need - but the problem is how to store it in pcString (directly)?

Or there is maybe a better solution to simply do it?

Body:
You want to split the string into individual tokens separated by spaces such as "I\0am\0testing\0". You can use strtok() for this but this function is error prone. I suggest you allocate an array of pointers and make them point to the words. Note that splitting the source string is sloppy and does not allow for tokens to be adjacent such as in 1+1. You could allocate the strings instead.

Here is an example:

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

char **split_string(const char *str, char *delim) {
    size_t i, len, count;
    const char *p;

    /* count tokens */
    p = str;
    p += strspn(p, delim);      // skip initial delimiters
    count = 0;
    while (*p) {
        count++;
        p += strcspn(p, delim); // skip token
        p += strspn(p, delim);  // skip delimiters
    }

    /* allocate token array */
    char **array = calloc(sizeof(*array, count + 1);
    p = str;
    p += strspn(p, delim);      // skip initial delimiters
    for (i = 0; i < count; i++) {
        len = strcspn(p, delim); // token length
        array[i] = strndup(p, len); // allocate a copy of the token
        p += len;               // skip token
        p += strspn(p, delim);  // skip delimiters
    }
    /* array ends with a null pointer */
    array[count] = NULL;
    return array;
}

int main() {
    const char *pcString = "I am testing";
    char **array = split_string(pcString, " \t\r\n");
    for (size_t i = 0; array[i] != NULL; i++) {
        printf("%zu: %s\n", i, array[i]);
    }
    return 0;
}


问:
WordPress editor made in React?
I have added 'React Developer Tools' as Chrome extension in my browser which shows me which all sites are using ReactJS. While writing a post today, I noticed that the extension shows my WordPress editor is using the production build of React.

Extension shows the editor is made in React

I quickly visited my WordPress site but the extension doesn't trigger there.

Actual WordPress site

So what is happening here? Is this just a bug in the extension? I know that you can use WordPress as a headless CMS in React but that is certainly not the case here.

答:
I suppose your wordpress editor just uses a component written with react that is not required on the website (maybe the editor itself?).

It's not uncommon practice. For example, if you add "Facebook comment plugin" on your website, it will add react on the background. If you have the react extension enabled, it will tell you that react has been found, even if it's used just for a little part of the website.

Moreover, I presume your readers are not meant to use the editor, so it make sense that they do not have to download it since is not required for them.

To confirm that's the case, you can open chrome dev tools and use the "network" - it would tell you exactly what resources have been requested by the current page.

Title: WordPress editor made in React?


问:
Suggestions for deploying AngularJS and NodeJS app
I'm building a basic web app using Angular, NodeJS, Express, and SQLite. The main concern here is pricing for a production environment. I want the cheapest way to deploy/maintain these. I chose SQLite so I don't have to worry about getting a production DB, though originally I wanted to use MongoDB. My question is, should I have my Angular and NodeJS app in the same project, and deploy my Angular app using express? Or should I have my Angular and NodeJS app separate? I originally had it together but was getting all kinds of errors. I did use a MEAN scaffolder which worked fine. But when I replaced MongoDB with TypeORM, I encountered the errors, so maybe my package.json/tsconfig.json was wrong? Regardless, what's the cheapest way to deploy my frontend and backend? I was thinking heroku/firebase, but want to hear some other suggestions</p>

答:
This could be quite a complex answer, but my short one would be to go serverless.

Use AWS S3 to host your AngularJS single page application

Cloudfront to expose your S3 bucket and host your site

Write a Node.js library for your backend and deploy to Lambda

Task AWS API Gateway to route requests to your library hosted on Lambda

Use Firebase for your database.

You now have very little infrastructure to worry about, your app is highly scaleable, and costs are basically zero until you hit a very considerable amount of traffic.


问:
Need select option by another input value
I have two inputs one is simple input another is select input with options. How can i achieve that when someone enters value for text input it automatically select correct option.

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

  Job code
  <input type="text" id="test2" name="jobcode[]" class="form-control">

  Job
  <select class="form-control" name="job[]" >
      <option value="1">Administrator - 1</option>
      <option value="2">Bartender - 2</option>
      <option value="3">Mechanic - 3</option>
      <option value="4">Bodybuilder - 4</option>
      <option value="5">Doctor- 5</option>
  </select>

```

答:
You can try this:

```<code>(function($) {
  $('#test2').on('blur', function(e) {
    let inputVal = $(this).val();

    $('#select option').each(function() {
      if ($(this).val() === inputVal) {
        $(this).prop('selected', true);
      }
    })
  });
})(jQuery);
</code>```

Here I get the inserted value at the input field on blur event. And check each option of the select if the value of the option is same as the input field's value. If so then change the selected prop of the option.

Body:
You can try this:

(function($) {
  $('#test2').on('blur', function(e) {
    let inputVal = $(this).val();

    $('#select option').each(function() {
      if ($(this).val() === inputVal) {
        $(this).prop('selected', true);
      }
    })
  });
})(jQuery);

Here I get the inserted value at the input field on blur event. And check each option of the select if the value of the option is same as the input field's value. If so then change the selected prop of the option.


问:
How to do batch display using NSTextView
I'd like to be able to show a view that resembles something like a console log, with multiple lines of text that are scrollable and selectable.

The fundamental procedure I have in mind is maintaining an array of strings (call it lines) and appending these to the textStorage of the NSTextView using a new line character as delimiter.

However there are a few factors to consider, such as:

Updating the textStorage on scroll so that it appears seamless to the user

Updating the textStorage on resizing the view height

Maintaining scroll position after the textStorage gets updated

Handling an out of memory possibility

Can someone please provide some guidance or a sample to get me started?

答:
Add a string from your array to the NSTextStorage and animate the NSClipView bounds origin.

- (void)appendText:(NSString*)string {
    // Add a newline, if you need to
    string = [NSString stringWithFormat:@"%@\n", string];

    // Find range
    [self.textView.textStorage replaceCharactersInRange:NSMakeRange(self.textView.textStorage.string.length, 0) withString:string];

    // Get clip view
    NSClipView *clipView = self.textView.enclosingScrollView.contentView;

    // Calculate the y position by subtracting
    // clip view height from total document height
    CGFloat scrollTo = self.textView.frame.size.height - clipView.frame.size.height;

    // Animate bounds
    [[clipView animator] setBoundsOrigin:NSMakePoint(0, scrollTo)];
}
```

<p>If you have elasticity set in your <code>NSTextView</code> you need to monitor for its frame changes to get exact results. Add <code>frameDidChange</code> listener to your text view and animate in the handler:</p>

<pre class="lang-c prettyprint-override"><code>- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Text view setup
    [_textView setPostsFrameChangedNotifications:YES];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToBottom) name:NSViewFrameDidChangeNotification object:_textView];
}

- (void)appendText:(NSString*)string {
    // Add a newline, if you need to
    string = [NSString stringWithFormat:@"%@\n", string];

    // Find range
    [self.textView.textStorage replaceCharactersInRange:NSMakeRange(self.textView.textStorage.string.length, 0) withString:string];
}

- (void)scrollToBottom {
    // Get the clip view and calculate y position
    NSClipView *clipView = self.textView.enclosingScrollView.contentView;

    // Y position for bottom is document's height - viewport height
    CGFloat scrollTo = self.textView.frame.size.height - clipView.frame.size.height;
    [[clipView animator] setBoundsOrigin:NSMakePoint(0, scrollTo)];
}
</code>```

In real-life application you would probably need to set some sort of threshold to see if the user has scrolled away from the end more than the height of a line.

Body:
Add a string from your array to the NSTextStorage and animate the NSClipView bounds origin.

- (void)appendText:(NSString*)string {
    // Add a newline, if you need to
    string = [NSString stringWithFormat:@"%@\n", string];

    // Find range
    [self.textView.textStorage replaceCharactersInRange:NSMakeRange(self.textView.textStorage.string.length, 0) withString:string];

    // Get clip view
    NSClipView *clipView = self.textView.enclosingScrollView.contentView;

    // Calculate the y position by subtracting
    // clip view height from total document height
    CGFloat scrollTo = self.textView.frame.size.height - clipView.frame.size.height;

    // Animate bounds
    [[clipView animator] setBoundsOrigin:NSMakePoint(0, scrollTo)];
}

If you have elasticity set in your NSTextView you need to monitor for its frame changes to get exact results. Add frameDidChange listener to your text view and animate in the handler:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Text view setup
    [_textView setPostsFrameChangedNotifications:YES];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollToBottom) name:NSViewFrameDidChangeNotification object:_textView];
}

- (void)appendText:(NSString*)string {
    // Add a newline, if you need to
    string = [NSString stringWithFormat:@"%@\n", string];

    // Find range
    [self.textView.textStorage replaceCharactersInRange:NSMakeRange(self.textView.textStorage.string.length, 0) withString:string];
}

- (void)scrollToBottom {
    // Get the clip view and calculate y position
    NSClipView *clipView = self.textView.enclosingScrollView.contentView;

    // Y position for bottom is document's height - viewport height
    CGFloat scrollTo = self.textView.frame.size.height - clipView.frame.size.height;
    [[clipView animator] setBoundsOrigin:NSMakePoint(0, scrollTo)];
}

In real-life application you would probably need to set some sort of threshold to see if the user has scrolled away from the end more than the height of a line.


问:
Returning multiple items from a function call in PHP
Is it possible to return multiple items from a function - and assign them to several variables in a single statement - like can be done in some languages (e.g. Python) ?

For example, can I have something like this:

```<code>a, b, c,d = foo();
</code>```

答:
A function can not return multiple values, but similar results can be obtained by returning an array.

```<code><?php
function small_numbers()
{
    return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>
</code>```

See http://php.net/manual/en/functions.returning-values.php

Body:
Is it possible to return multiple items from a function - and assign them to several variables in a single statement - like can be done in some languages (e.g. Python) ?

For example, can I have something like this:

a, b, c,d = foo();

Body:
A function can not return multiple values, but similar results can be obtained by returning an array.

<?php
function small_numbers()
{
    return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
?>

See http://php.net/manual/en/functions.returning-values.php


问:
Lock as a member of entity vs synchronized (best practice)
Let's say I have an EntityPool. After I get an entity from the pool, I need to modify the entity in a thread-safe way. So I see 2 choices:

1) Using synchronized:

```<code>Entity e = pool.getById(id);
synchronized (e) {
    // modifying e
}
</code>```

2) Add a lock to the Entity class and use it:

```<code>Entity e = pool.getById(id);
Lock l = e.getLock();
try {
    l.lock();
    // modifying e
} finally {
    l.unlock();
}
</code>```

I've heard that I should avoid using "synchronized" keyword. Should I use lock instead? But it seems weird to me that the Entity class should know anything about synchronization.

答:
Use 'synchronized' if your usage follows lexical scope. Synchronization starts when you enter a synchronized method or the body of a synchronized {…} clause, and ends when you leave it.

By contrast, locking and unlocking can be applied to arbitrary sequences of actions.  You can, for example, acquire the lock in a call to some sort of 'startSomething' method, and release the lock in a later call to an 'endSomething' method.  The cost of this is your need to ensure correctness.

tl;dr - use synchronized unless it clearly doesn't work for your use case.

Body:
Let's say I have an EntityPool. After I get an entity from the pool, I need to modify the entity in a thread-safe way. So I see 2 choices:

1) Using synchronized:

Entity e = pool.getById(id);
synchronized (e) {
    // modifying e
}

2) Add a lock to the Entity class and use it:

Entity e = pool.getById(id);
Lock l = e.getLock();
try {
    l.lock();
    // modifying e
} finally {
    l.unlock();
}

I've heard that I should avoid using "synchronized" keyword. Should I use lock instead? But it seems weird to me that the Entity class should know anything about synchronization.


问:
Highcharts Double Click To Select
I'm currently using Highcharts v8.1.0 and I'm implementing a column chart with drill down functionality.

I'd like to implement the following:

When a user double-clicks a column in the chart, the column is selected. Once the user has finished selecting one or more columns I'd like to use the column data to apply some filtering in another part of my application so wondering if there's a way to get all the selected items and their associated data?

When a user just single-clicks a column, the default drill down behavior happens (this currently works)

I'm using the highcharts-custom-events plugin and can capture double-click events, but can't figure out how to set the column that was clicked as selected.

Here's my plotOptions configuration:

```<code>plotOptions: {
        column: {
          events: {
            dblclick: function(e){
              self.dblClickDetected = true;
              this.selected = true;
              console.log('DOUBLE CLICK', self.chart.getSelectedSeries())
            }
          }
        }
</code>```

Here's the configuration for the drilldown event:

```<code>drilldown: (event) => {
            event.preventDefault();
            setTimeout(() => {
              if(!this.dblClickDetected){
                ...do something here...
              }
            }, 500);
            this.dblClickDetected = false;
          }
</code>```

The behavior for single-click and double-click can be reversed if it makes it easier to implement.

答:
I prepared a demo which should help you to achieve a wanted effect.

Demo: https://jsfiddle.net/BlackLabel/7aubt81y/

```<code> plotOptions: {
    column: {
      point: {
        events: {
          dblclick: function(e) {
            if (this.state !== 'select') {
              this.update({
                selected: true
              })
            } else {
              this.update({
                selected: false
              })
            }

          }
        }
      }
    }
  },
</code>```

API: https://api.highcharts.com/highcharts/series.line.selected

API: https://api.highcharts.com/class-reference/Highcharts.Point#update

EDIT

After digging more into this requirement I think that the best solution for this case will be creating a custom drilldown event. Below is a basic demo which should be a good start to implement it.

Demo: https://jsfiddle.net/BlackLabel/21utpsoy/

The reason is that drilldown module with the dbclick functionality throws some errors, see: https://jsfiddle.net/BlackLabel/copL4h36/.

API to used features:

https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#button

https://api.highcharts.com/class-reference/Highcharts.Series#update

Title: Highcharts Double Click To Select

Body:
I'm currently using Highcharts v8.1.0 and I'm implementing a column chart with drill down functionality.

I'd like to implement the following:

When a user double-clicks a column in the chart, the column is selected. Once the user has finished selecting one or more columns I'd like to use the column data to apply some filtering in another part of my application so wondering if there's a way to get all the selected items and their associated data?

When a user just single-clicks a column, the default drill down behavior happens (this currently works)

I'm using the highcharts-custom-events plugin and can capture double-click events, but can't figure out how to set the column that was clicked as selected.

Here's my plotOptions configuration:

plotOptions: {
        column: {
          events: {
            dblclick: function(e){
              self.dblClickDetected = true;
              this.selected = true;
              console.log('DOUBLE CLICK', self.chart.getSelectedSeries())
            }
          }
        }

Here's the configuration for the drilldown event:

drilldown: (event) => {
            event.preventDefault();
            setTimeout(() => {
              if(!this.dblClickDetected){
                ...do something here...
              }
            }, 500);
            this.dblClickDetected = false;
          }

The behavior for single-click and double-click can be reversed if it makes it easier to implement.

Body:
I prepared a demo which should help you to achieve a wanted effect.

Demo: https://jsfiddle.net/BlackLabel/7aubt81y/

 plotOptions: {
    column: {
      point: {
        events: {
          dblclick: function(e) {
            if (this.state !== 'select') {
              this.update({
                selected: true
              })
            } else {
              this.update({
                selected: false
              })
            }

          }
        }
      }
    }
  },

API: https://api.highcharts.com/highcharts/series.line.selected

API: https://api.highcharts.com/class-reference/Highcharts.Point#update

EDIT

After digging more into this requirement I think that the best solution for this case will be creating a custom drilldown event. Below is a basic demo which should be a good start to implement it.

Demo: https://jsfiddle.net/BlackLabel/21utpsoy/

The reason is that drilldown module with the dbclick functionality throws some errors, see: https://jsfiddle.net/BlackLabel/copL4h36/.

API to used features:

https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#button

https://api.highcharts.com/class-reference/Highcharts.Series#update


问:
Issues with Expo Auth Session implementation
I am having issues with the implementation of Expo Auth Session.

I am trying Google Oauth Login in Expo Auth Session as documented here: https://docs.expo.io/guides/authentication/#google

```<code>WebBrowser.maybeCompleteAuthSession();

const GoogleButton = () => {
  // Endpoint
  const discovery = useAutoDiscovery('https://accounts.google.com');

  // Request
  const [request, response, promptAsync] = useAuthRequest(
    {
      clientId: 'MYID',
      scopes: ['email', 'profile'],
      // For usage in managed apps using the proxy
      redirectUri: makeRedirectUri({
        // For usage in bare and standalone
        native: 'com.googleusercontent.apps.MYID://redirect',
        useProxy: true,
      }),
    },
    discovery,
  );

  console.log(request);
  console.log(response);

  return (
    <Button
      onPress={promptAsync}
      icon={GoogleIcon}
    />
  );
};
</code>```

The browser opens, I can successfully log in with google, but when I get redirected to the app, response resolves to Object { "type": "dismiss", }

I also tried implementing oauth with a different oauth service:

```<code>WebBrowser.maybeCompleteAuthSession();

const HiveButton = () => {
  // Endpoint
  const discovery = {
    authorizationEndpoint:
      'https://hivesigner.com/login-request/my.app',
  };

  // Request
  const [request, response, promptAsync] = useAuthRequest(
    {
      scopes: ['posting'],
      // For usage in managed apps using the proxy
      redirectUri: makeRedirectUri({
        useProxy: true,
      }),
    },
    discovery,
  );

  console.log(request);
  console.log(response);

  return (
    <Button
      onPress={promptAsync}
      icon={HiveIcon}
    />
  );
};
</code>```

The browser opens, I can log in successfully, but instead of being redirected to the app, I get "Something went wrong trying to finish signing in. Please close this screen to go back to the app." on auth.expo.io/@me/myapp, even though the parameter code has the correct login token that I want to pass to my app.

答:
I’ve now solved the second issue by using AuthSession.startAsync instead:

```<code> const handleLogin = async () => {
    const redirectUrl = AuthSession.getRedirectUrl({ useProxy: true });
    const response = await AuthSession.startAsync({
      authUrl: `https://hivesigner.com/login-request/my.app?redirect_uri=${redirectUrl}&scope=posting`,
    });
console.log(response)
}
</code>```

Instead of using AuthSession for Google login I’m using the expo-google-sign-in implementation

Body:
I am having issues with the implementation of Expo Auth Session.

I am trying Google Oauth Login in Expo Auth Session as documented here: https://docs.expo.io/guides/authentication/#google

WebBrowser.maybeCompleteAuthSession();

const GoogleButton = () => {
  // Endpoint
  const discovery = useAutoDiscovery('https://accounts.google.com');

  // Request
  const [request, response, promptAsync] = useAuthRequest(
    {
      clientId: 'MYID',
      scopes: ['email', 'profile'],
      // For usage in managed apps using the proxy
      redirectUri: makeRedirectUri({
        // For usage in bare and standalone
        native: 'com.googleusercontent.apps.MYID://redirect',
        useProxy: true,
      }),
    },
    discovery,
  );

  console.log(request);
  console.log(response);

  return (
    <Button
      onPress={promptAsync}
      icon={GoogleIcon}
    />
  );
};

The browser opens, I can successfully log in with google, but when I get redirected to the app, response resolves to Object { "type": "dismiss", }

I also tried implementing oauth with a different oauth service:

WebBrowser.maybeCompleteAuthSession();

const HiveButton = () => {
  // Endpoint
  const discovery = {
    authorizationEndpoint:
      'https://hivesigner.com/login-request/my.app',
  };

  // Request
  const [request, response, promptAsync] = useAuthRequest(
    {
      scopes: ['posting'],
      // For usage in managed apps using the proxy
      redirectUri: makeRedirectUri({
        useProxy: true,
      }),
    },
    discovery,
  );

  console.log(request);
  console.log(response);

  return (
    <Button
      onPress={promptAsync}
      icon={HiveIcon}
    />
  );
};

The browser opens, I can log in successfully, but instead of being redirected to the app, I get "Something went wrong trying to finish signing in. Please close this screen to go back to the app." on auth.expo.io/@me/myapp, even though the parameter code has the correct login token that I want to pass to my app.

Body:
I’ve now solved the second issue by using AuthSession.startAsync instead:

 const handleLogin = async () => {
    const redirectUrl = AuthSession.getRedirectUrl({ useProxy: true });
    const response = await AuthSession.startAsync({
      authUrl: `https://hivesigner.com/login-request/my.app?redirect_uri=${redirectUrl}&scope=posting`,
    });
console.log(response)
}

Instead of using AuthSession for Google login I’m using the expo-google-sign-in implementation