问:
React Native: Touchable Opacity element is clickable on iOS but not Android
I'm working on a React Native app with a typeahead component. The typeahead displays options that overlay other content on the route (see right image below). When a user clicks one of those options, an onPress listener runs a function:

This all works just fine on iOS. On Android though, the onPress event is never received. Even more strangely, when I try to click on an option lower in the list (like Boston, MA, USA), the onPress event is received by the card below the pressed option (Djerba).

Does anyone know what might cause this behavior? I'd be super grateful for any insights others can offer on this query.

Here's the code for the Explore view and the typeahead components.

Explore.js

```<code>import React from 'react'
import { connect } from 'react-redux'
import { Text, View, ScrollView, TouchableOpacity } from 'react-native'
import { gradients, sizing } from '../../style'
import { LinearGradient } from 'expo-linear-gradient'
import { MountainHero } from '../Heros'
import { CardRow } from '../Card'
import Loading from '../Loading'
import { setExploreSearch, onExploreTypeaheadClick } from '../../actions/locations'
import { Typeahead } from '../Typeahead'

const styles = {
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  scrollView: {
    paddingBottom: sizing.margin,
  },
  loadingContainer: {
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 100,
    elevation: 100,
    top: 53,
    width: '100%',
  },
  typeahead: {
    margin: sizing.margin,
    marginBottom: 0,
    width: sizing.screen.width - (2*sizing.margin),
    zIndex: 100,
    elevation: 100,
  }
}

const Explore = props => {
  const { authenticated: a, spotlight, loading } = props;
  let r = (a.recommendedLocations || []);
  if (!r || !spotlight) return null;
  // remove spotlight locations from the recommended locations
  const ids = spotlight.map(i => i.guid);
  const recommended = r.filter(i => ids.indexOf(i.guid) == -1);
  return (
    <LinearGradient style={styles.container} colors={gradients.teal}>
      <ScrollView contentContainerStyle={styles.scrollView}>
        {loading && (
          <View style={styles.loadingContainer}>
            <Loading />
          </View>
        )}
        <MountainHero text='Explore' />
        <Typeahead
          style={styles.typeahead}
          placeholder='Search Cities'
          value={props.exploreSearch}
          onChange={props.setExploreSearch}
          vals={props.exploreTypeahead}
          valKey={'place_id'}
          onTypeaheadClick={props.onExploreTypeaheadClick}
        />
        <CardRow
          text='Explore Places'
          cards={recommended}
          type='location' />
        <CardRow
          text='In the Spotlight'
          cards={spotlight}
          type='location' />
      </ScrollView>
    </LinearGradient>
  )
}

const mapStateToProps = state => ({
  authenticated: state.users.authenticated,
  spotlight: state.locations.spotlight,
  exploreSearch: state.locations.exploreSearch,
  exploreTypeahead: state.locations.exploreTypeahead,
  loading: state.locations.loading,
})

const mapDispatchToProps = dispatch => ({
  setExploreSearch: s => dispatch(setExploreSearch(s)),
  onExploreTypeaheadClick: val => dispatch(onExploreTypeaheadClick(val)),
})

export default connect(mapStateToProps, mapDispatchToProps)(Explore)
</code>```

Typeahead.js

```<code>import React from 'react'
import { Text, View, TouchableOpacity } from 'react-native'
import { sizing, GradientInput } from '../style'

const styles = {
  container: {
    position: 'absolute',
    zIndex: 100,
    elevation: 100,
    height: 400,
    width: '100%',
  },
  input: {
    width: '100%',
    borderRadius: 0,
  },
  typeaheadContainer: {
    position: 'absolute',
    zIndex: 100,
    elevation: 100,
    top: 55,
    width: '100%',
  },
  typeaheadRow: {
    padding: 10,
    paddingTop: 12,
    paddingBottom: 12,
    borderWidth: 1,
    borderColor: '#eeeeee',
    backgroundColor: '#ffffff',
    marginBottom: -1,
  },
  typeaheadRowText: {
    fontSize: 15,
    fontFamily: 'open-sans',
    lineHeight: 20,
    backgroundColor: '#ffffff',
  },
}

export const Typeahead = props => {
  return (
    <View style={[props.container, props.style]}>
      <GradientInput style={styles.input}
        placeholder={props.placeholder}
        value={props.value}
        onChange={props.onChange} />
      <TypeaheadList vals={props.vals}
        valKey={props.valKey}
        onTypeaheadClick={props.onTypeaheadClick} />
    </View>
  )
}

export const TypeaheadList = props => {
  if (!props.vals) return null;
  return (
    <View style={styles.typeaheadContainer}>
      {props.vals.map(i => {
        let text = i.text;
        if (text.length > 31) text = text.substring(0,31) + '...';
        return (
          <TouchableOpacity activeOpacity={0.5} key={i[props.valKey]}
            style={styles.typeaheadRow}
            onPress={() => props.onTypeaheadClick(i[props.valKey])}>
            <Text numberOfLines={1} style={styles.typeaheadRowText}>{text}</Text>
          </TouchableOpacity>
        )
      })}
    </View>
  )
}

export default Typeahead
</code>```

答:
Try to move Typeahead component below all CardRow components and set position:absolute for Typeahead. Probably on android - the latest view shadow all views before (I am not sure, but I think you have to try it for next discovering issue).

You should also remove position: absolute from all but one component. Working code:

Explore.js

```<code>import React from 'react'
import { connect } from 'react-redux'
import { Text, View, ScrollView, TouchableOpacity } from 'react-native'
import { gradients, sizing } from '../../style'
import { LinearGradient } from 'expo-linear-gradient'
import { MountainHero } from '../Heros'
import { CardRow } from '../Card'
import Loading from '../Loading'
import { setExploreSearch, onExploreTypeaheadClick } from '../../actions/locations'
import { Typeahead } from '../Typeahead'
const styles = {
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  scrollView: {
    paddingBottom: sizing.margin,
  },
  loadingContainer: {
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
    elevation: 1,
    top: 53,
    width: '100%',
  },
  topCardRow: {
    paddingTop: sizing.margin + sizing.gradientInput.height,
  },
  typeahead: {
    margin: sizing.margin,
    marginBottom: 0,
    width: sizing.screen.width - (2*sizing.margin),
    zIndex: 1,
    elevation: 1,
    position: 'absolute',
    top: sizing.mountainHero.height,
    left: 0,
  }
}
const Explore = props => {
  const { authenticated: a, spotlight, loading } = props;
  let r = (a.recommendedLocations || []);
  if (!r || !spotlight) return null;
  // remove spotlight locations from the recommended locations
  const ids = spotlight.map(i => i.guid);
  const recommended = r.filter(i => ids.indexOf(i.guid) == -1);
  return (
    <LinearGradient style={styles.container} colors={gradients.teal}>
      <ScrollView contentContainerStyle={styles.scrollView}>
        {loading && (
          <View style={styles.loadingContainer}>
            <Loading />
          </View>
        )}
        <MountainHero text='Explore' />
        <CardRow
          style={styles.topCardRow}
          text='Explore Places'
          cards={recommended}
          type='location' />
        <CardRow
          text='In the Spotlight'
          cards={spotlight}
          type='location' />
        <Typeahead
          style={styles.typeahead}
          placeholder='Search Cities'
          value={props.exploreSearch}
          onChange={props.setExploreSearch}
          vals={props.exploreTypeahead}
          valKey={'place_id'}
          onTypeaheadClick={props.onExploreTypeaheadClick}
        />
      </ScrollView>
    </LinearGradient>
  )
}
const mapStateToProps = state => ({
  authenticated: state.users.authenticated,
  spotlight: state.locations.spotlight,
  exploreSearch: state.locations.exploreSearch,
  exploreTypeahead: state.locations.exploreTypeahead,
  loading: state.locations.loading,
})
const mapDispatchToProps = dispatch => ({
  setExploreSearch: s => dispatch(setExploreSearch(s)),
  onExploreTypeaheadClick: val => dispatch(onExploreTypeaheadClick(val)),
})
export default connect(mapStateToProps, mapDispatchToProps)(Explore)
</code>```

Typeahead.js

```<code>import React from 'react'
import { Text, View, TouchableOpacity } from 'react-native'
import { sizing, GradientInput } from '../style'

const styles = {
  container: {
    zIndex: 1,
    elevation: 1,
    height: 400,
    width: '100%',
  },
  input: {
    width: '100%',
    borderRadius: 0,
  },
  typeaheadContainer: {
    zIndex: 1,
    elevation: 1,
    top: 0,
    width: '100%',
  },
  typeaheadRow: {
    padding: 10,
    paddingTop: 12,
    paddingBottom: 12,
    borderWidth: 1,
    borderColor: '#eeeeee',
    backgroundColor: '#ffffff',
    marginBottom: -1,
    zIndex: 1,
    elevation: 1,
  },
  typeaheadRowText: {
    fontSize: 15,
    fontFamily: 'open-sans',
    lineHeight: 20,
    backgroundColor: '#ffffff',
  },
}

export const Typeahead = props => {
  return (
    <View style={[props.container, props.style]}>
      <GradientInput style={styles.input}
        placeholder={props.placeholder}
        value={props.value}
        onChange={props.onChange} />
      <TypeaheadList vals={props.vals}
        valKey={props.valKey}
        onTypeaheadClick={props.onTypeaheadClick} />
    </View>
  )
}

export const TypeaheadList = props => {
  if (!props.vals) return null;
  return (
    <View style={styles.typeaheadContainer}>
      {props.vals.map(i => {
        let text = i.text;
        if (text.length > 31) text = text.substring(0,31) + '...';
        return (
          <TouchableOpacity activeOpacity={0.5} key={i[props.valKey]}
            style={styles.typeaheadRow}
            onPress={() => props.onTypeaheadClick(i[props.valKey])}>
            <Text numberOfLines={1} style={styles.typeaheadRowText}>{text}</Text>
          </TouchableOpacity>
        )
      })}
    </View>
  )
}

export default Typeahead
</code>```

Body:
I'm working on a React Native app with a typeahead component. The typeahead displays options that overlay other content on the route (see right image below). When a user clicks one of those options, an onPress listener runs a function:

This all works just fine on iOS. On Android though, the onPress event is never received. Even more strangely, when I try to click on an option lower in the list (like Boston, MA, USA), the onPress event is received by the card below the pressed option (Djerba).

Does anyone know what might cause this behavior? I'd be super grateful for any insights others can offer on this query.

Here's the code for the Explore view and the typeahead components.

Explore.js

import React from 'react'
import { connect } from 'react-redux'
import { Text, View, ScrollView, TouchableOpacity } from 'react-native'
import { gradients, sizing } from '../../style'
import { LinearGradient } from 'expo-linear-gradient'
import { MountainHero } from '../Heros'
import { CardRow } from '../Card'
import Loading from '../Loading'
import { setExploreSearch, onExploreTypeaheadClick } from '../../actions/locations'
import { Typeahead } from '../Typeahead'

const styles = {
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  scrollView: {
    paddingBottom: sizing.margin,
  },
  loadingContainer: {
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 100,
    elevation: 100,
    top: 53,
    width: '100%',
  },
  typeahead: {
    margin: sizing.margin,
    marginBottom: 0,
    width: sizing.screen.width - (2*sizing.margin),
    zIndex: 100,
    elevation: 100,
  }
}

const Explore = props => {
  const { authenticated: a, spotlight, loading } = props;
  let r = (a.recommendedLocations || []);
  if (!r || !spotlight) return null;
  // remove spotlight locations from the recommended locations
  const ids = spotlight.map(i => i.guid);
  const recommended = r.filter(i => ids.indexOf(i.guid) == -1);
  return (
    <LinearGradient style={styles.container} colors={gradients.teal}>
      <ScrollView contentContainerStyle={styles.scrollView}>
        {loading && (
          <View style={styles.loadingContainer}>
            <Loading />
          </View>
        )}
        <MountainHero text='Explore' />
        <Typeahead
          style={styles.typeahead}
          placeholder='Search Cities'
          value={props.exploreSearch}
          onChange={props.setExploreSearch}
          vals={props.exploreTypeahead}
          valKey={'place_id'}
          onTypeaheadClick={props.onExploreTypeaheadClick}
        />
        <CardRow
          text='Explore Places'
          cards={recommended}
          type='location' />
        <CardRow
          text='In the Spotlight'
          cards={spotlight}
          type='location' />
      </ScrollView>
    </LinearGradient>
  )
}

const mapStateToProps = state => ({
  authenticated: state.users.authenticated,
  spotlight: state.locations.spotlight,
  exploreSearch: state.locations.exploreSearch,
  exploreTypeahead: state.locations.exploreTypeahead,
  loading: state.locations.loading,
})

const mapDispatchToProps = dispatch => ({
  setExploreSearch: s => dispatch(setExploreSearch(s)),
  onExploreTypeaheadClick: val => dispatch(onExploreTypeaheadClick(val)),
})

export default connect(mapStateToProps, mapDispatchToProps)(Explore)

Typeahead.js

import React from 'react'
import { Text, View, TouchableOpacity } from 'react-native'
import { sizing, GradientInput } from '../style'

const styles = {
  container: {
    position: 'absolute',
    zIndex: 100,
    elevation: 100,
    height: 400,
    width: '100%',
  },
  input: {
    width: '100%',
    borderRadius: 0,
  },
  typeaheadContainer: {
    position: 'absolute',
    zIndex: 100,
    elevation: 100,
    top: 55,
    width: '100%',
  },
  typeaheadRow: {
    padding: 10,
    paddingTop: 12,
    paddingBottom: 12,
    borderWidth: 1,
    borderColor: '#eeeeee',
    backgroundColor: '#ffffff',
    marginBottom: -1,
  },
  typeaheadRowText: {
    fontSize: 15,
    fontFamily: 'open-sans',
    lineHeight: 20,
    backgroundColor: '#ffffff',
  },
}

export const Typeahead = props => {
  return (
    <View style={[props.container, props.style]}>
      <GradientInput style={styles.input}
        placeholder={props.placeholder}
        value={props.value}
        onChange={props.onChange} />
      <TypeaheadList vals={props.vals}
        valKey={props.valKey}
        onTypeaheadClick={props.onTypeaheadClick} />
    </View>
  )
}

export const TypeaheadList = props => {
  if (!props.vals) return null;
  return (
    <View style={styles.typeaheadContainer}>
      {props.vals.map(i => {
        let text = i.text;
        if (text.length > 31) text = text.substring(0,31) + '...';
        return (
          <TouchableOpacity activeOpacity={0.5} key={i[props.valKey]}
            style={styles.typeaheadRow}
            onPress={() => props.onTypeaheadClick(i[props.valKey])}>
            <Text numberOfLines={1} style={styles.typeaheadRowText}>{text}</Text>
          </TouchableOpacity>
        )
      })}
    </View>
  )
}

export default Typeahead

Body:
Try to move Typeahead component below all CardRow components and set position:absolute for Typeahead. Probably on android - the latest view shadow all views before (I am not sure, but I think you have to try it for next discovering issue).

You should also remove position: absolute from all but one component. Working code:

Explore.js

import React from 'react'
import { connect } from 'react-redux'
import { Text, View, ScrollView, TouchableOpacity } from 'react-native'
import { gradients, sizing } from '../../style'
import { LinearGradient } from 'expo-linear-gradient'
import { MountainHero } from '../Heros'
import { CardRow } from '../Card'
import Loading from '../Loading'
import { setExploreSearch, onExploreTypeaheadClick } from '../../actions/locations'
import { Typeahead } from '../Typeahead'
const styles = {
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  scrollView: {
    paddingBottom: sizing.margin,
  },
  loadingContainer: {
    position: 'absolute',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1,
    elevation: 1,
    top: 53,
    width: '100%',
  },
  topCardRow: {
    paddingTop: sizing.margin + sizing.gradientInput.height,
  },
  typeahead: {
    margin: sizing.margin,
    marginBottom: 0,
    width: sizing.screen.width - (2*sizing.margin),
    zIndex: 1,
    elevation: 1,
    position: 'absolute',
    top: sizing.mountainHero.height,
    left: 0,
  }
}
const Explore = props => {
  const { authenticated: a, spotlight, loading } = props;
  let r = (a.recommendedLocations || []);
  if (!r || !spotlight) return null;
  // remove spotlight locations from the recommended locations
  const ids = spotlight.map(i => i.guid);
  const recommended = r.filter(i => ids.indexOf(i.guid) == -1);
  return (
    <LinearGradient style={styles.container} colors={gradients.teal}>
      <ScrollView contentContainerStyle={styles.scrollView}>
        {loading && (
          <View style={styles.loadingContainer}>
            <Loading />
          </View>
        )}
        <MountainHero text='Explore' />
        <CardRow
          style={styles.topCardRow}
          text='Explore Places'
          cards={recommended}
          type='location' />
        <CardRow
          text='In the Spotlight'
          cards={spotlight}
          type='location' />
        <Typeahead
          style={styles.typeahead}
          placeholder='Search Cities'
          value={props.exploreSearch}
          onChange={props.setExploreSearch}
          vals={props.exploreTypeahead}
          valKey={'place_id'}
          onTypeaheadClick={props.onExploreTypeaheadClick}
        />
      </ScrollView>
    </LinearGradient>
  )
}
const mapStateToProps = state => ({
  authenticated: state.users.authenticated,
  spotlight: state.locations.spotlight,
  exploreSearch: state.locations.exploreSearch,
  exploreTypeahead: state.locations.exploreTypeahead,
  loading: state.locations.loading,
})
const mapDispatchToProps = dispatch => ({
  setExploreSearch: s => dispatch(setExploreSearch(s)),
  onExploreTypeaheadClick: val => dispatch(onExploreTypeaheadClick(val)),
})
export default connect(mapStateToProps, mapDispatchToProps)(Explore)

Typeahead.js

import React from 'react'
import { Text, View, TouchableOpacity } from 'react-native'
import { sizing, GradientInput } from '../style'

const styles = {
  container: {
    zIndex: 1,
    elevation: 1,
    height: 400,
    width: '100%',
  },
  input: {
    width: '100%',
    borderRadius: 0,
  },
  typeaheadContainer: {
    zIndex: 1,
    elevation: 1,
    top: 0,
    width: '100%',
  },
  typeaheadRow: {
    padding: 10,
    paddingTop: 12,
    paddingBottom: 12,
    borderWidth: 1,
    borderColor: '#eeeeee',
    backgroundColor: '#ffffff',
    marginBottom: -1,
    zIndex: 1,
    elevation: 1,
  },
  typeaheadRowText: {
    fontSize: 15,
    fontFamily: 'open-sans',
    lineHeight: 20,
    backgroundColor: '#ffffff',
  },
}

export const Typeahead = props => {
  return (
    <View style={[props.container, props.style]}>
      <GradientInput style={styles.input}
        placeholder={props.placeholder}
        value={props.value}
        onChange={props.onChange} />
      <TypeaheadList vals={props.vals}
        valKey={props.valKey}
        onTypeaheadClick={props.onTypeaheadClick} />
    </View>
  )
}

export const TypeaheadList = props => {
  if (!props.vals) return null;
  return (
    <View style={styles.typeaheadContainer}>
      {props.vals.map(i => {
        let text = i.text;
        if (text.length > 31) text = text.substring(0,31) + '...';
        return (
          <TouchableOpacity activeOpacity={0.5} key={i[props.valKey]}
            style={styles.typeaheadRow}
            onPress={() => props.onTypeaheadClick(i[props.valKey])}>
            <Text numberOfLines={1} style={styles.typeaheadRowText}>{text}</Text>
          </TouchableOpacity>
        )
      })}
    </View>
  )
}

export default Typeahead


来源: stackexchange

问:
Why does Bottom Sheet Dialog not expand on tablet?
I have impelemented a BottomSheetDialog in my app but when I install it on a tablet and have the tablet laying down it does not expand fully on first click. It expands up to Collapsed state first and you have to drag it up to see everything. Why does it do this? Is it some setting you can change in your style?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
    app:behavior_peekHeight="0dp"
    >
   ...

</LinearLayout>
```

<pre class="lang-java prettyprint-override"><code>val view = layoutInflater.inflate(R.layout.home_bottom_sheet_dialog, null)
val bottomSheetDialog = BottomSheetDialog(activity!!)

bottomSheetDialog.setContentView(view)
bottomSheetDialog.show()
</code>```

I use API 22 AndroidX with kotlin.

答:
Implementing fully expanded bottom sheet a little tricky. You should override onViewCreated method in your BottomSheetDialogFragment class and listen GlobalLayout as below:

(Java Code)

```<code>@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
        BottomSheetDialog dialog = (BottomSheetDialog) getDialog();

        if (dialog != null) {
            FrameLayout bottomSheet = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
            if (bottomSheet != null) {

                BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                bottomSheetBehavior.setPeekHeight(0);

                bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                    @Override
                    public void onStateChanged(@NonNull View view1, int i) {
                        if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED || bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
                            if (!isStateSaved())
                                dismissAllowingStateLoss();
                        }
                    }

                    @Override
                    public void onSlide(@NonNull View view1, float v) {
                    }
                });
            }
        }
    });
}
</code>```

Additionally no need that attributes in xml:

```<code>app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_peekHeight="0dp"
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have impelemented a BottomSheetDialog in my app but when I install it on a tablet and have the tablet laying down it does not expand fully on first click. It expands up to Collapsed state first and you have to drag it up to see everything. Why does it do this? Is it some setting you can change in your style?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
    app:behavior_peekHeight="0dp"
    >
   ...

</LinearLayout>

val view = layoutInflater.inflate(R.layout.home_bottom_sheet_dialog, null)
val bottomSheetDialog = BottomSheetDialog(activity!!)

bottomSheetDialog.setContentView(view)
bottomSheetDialog.show()

I use API 22 AndroidX with kotlin.

Body:
Implementing fully expanded bottom sheet a little tricky. You should override onViewCreated method in your BottomSheetDialogFragment class and listen GlobalLayout as below:

(Java Code)

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
        BottomSheetDialog dialog = (BottomSheetDialog) getDialog();

        if (dialog != null) {
            FrameLayout bottomSheet = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
            if (bottomSheet != null) {

                BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                bottomSheetBehavior.setPeekHeight(0);

                bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
                    @Override
                    public void onStateChanged(@NonNull View view1, int i) {
                        if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED || bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN) {
                            if (!isStateSaved())
                                dismissAllowingStateLoss();
                        }
                    }

                    @Override
                    public void onSlide(@NonNull View view1, float v) {
                    }
                });
            }
        }
    });
}

Additionally no need that attributes in xml:

app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
app:behavior_peekHeight="0dp"


问:
POV-Ray 2D gradient (polygon)
So, what I want to do is apply a color gradient on a custom 2D polygon and I can't find anywhere instructions/examples on how to do it (all I can find are 3D ones). Specifically, I want to do this:

Also in general, I would like to know how to apply a simple radial gradient say from the center (of the polygon) out.

答:
Ok, so I figured it out and since I can't seem to find a straight-forward answer anywhere I might as well answer my own question:

1) To do one gradient on your polygon you just need the spherical pigment with a color_map. I give an example with a triangle:

```<code>#declare pol1=polygon{3,<-1,0> <1,0> <0,1>} //Declare a triangle
polygon{pol1 pigment{spherical color_map{[0.0 rgb <1,0,0>] [1.0 rgb <0,0,1>] } translate<0,0,0>} }
</code>```

So what this does is it creates a radial gradient with its center at the absolute (0,0,0) and you can translate it depending where you want it. The color map defines two colors (rgb <1,0,0> and rgb <0,0,1>) and the number in front of them basically controls the gradient (where the colors start/end relative to the grid system). Won't explain it in detail so you can read more here.

2) To do more gradients, say one for each corner I couldn't find a way to apply 3 different gradients on a single shape. Like color_map there is also a gradient_map but it's of no help because of the way you have to define where one pigment ends and where the next one starts. So the only way I found around this is by removing the polygon's corners with cylinders (with the difference command) and then replace them with cylinders (with the intersection command) whose phase is the desired gradient. And even though it's a messy way it doesn't actually impacts performance which is my main concern so I'm going with it until I find something better. So here is an example (I am not going to explain it any further, this answer is getting big as it is):

```<code>#declare pos1=array[2]{-1,0}; //the corners' coordinates
#declare pos2=array[2]{1,0};
#declare pos3=array[2]{0,1};
#declare cyl_rad=0.5;

#declare pol1=polygon{3,<pos1[0],pos1[1],0> <pos2[0],pos2[1],0> <pos3[0],pos3[1],0>} //Declare the polygon
#declare cyl1=cylinder{<pos1[0],pos1[1],-0.01> <pos1[0],pos1[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the first corner
#declare cyl2=cylinder{<pos2[0],pos2[1],-0.01> <pos2[0],pos2[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the second corner
#declare cyl3=cylinder{<pos3[0],pos3[1],-0.01> <pos3[0],pos3[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the third corner
difference{polygon{pol1} cyl1 cyl2 cyl3 pigment {color_part}} //The polygon with its corners "cut"
intersection{polygon{pol1} cyl3 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,0,1>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos3[0],pos3[1],0>} } //Replacing the corners with the coloured cylinders
intersection{polygon{pol1} cyl2 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,1,1>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos2[0],pos2[1],0>} }
intersection{polygon{pol1} cyl1 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,1,0>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos1[0],pos1[1],0>} }
</code>```

Title: POV-Ray 2D gradient (polygon)

Body:
Ok, so I figured it out and since I can't seem to find a straight-forward answer anywhere I might as well answer my own question:

1) To do one gradient on your polygon you just need the spherical pigment with a color_map. I give an example with a triangle:

#declare pol1=polygon{3,<-1,0> <1,0> <0,1>} //Declare a triangle
polygon{pol1 pigment{spherical color_map{[0.0 rgb <1,0,0>] [1.0 rgb <0,0,1>] } translate<0,0,0>} }

So what this does is it creates a radial gradient with its center at the absolute (0,0,0) and you can translate it depending where you want it. The color map defines two colors (rgb <1,0,0> and rgb <0,0,1>) and the number in front of them basically controls the gradient (where the colors start/end relative to the grid system). Won't explain it in detail so you can read more here.

2) To do more gradients, say one for each corner I couldn't find a way to apply 3 different gradients on a single shape. Like color_map there is also a gradient_map but it's of no help because of the way you have to define where one pigment ends and where the next one starts. So the only way I found around this is by removing the polygon's corners with cylinders (with the difference command) and then replace them with cylinders (with the intersection command) whose phase is the desired gradient. And even though it's a messy way it doesn't actually impacts performance which is my main concern so I'm going with it until I find something better. So here is an example (I am not going to explain it any further, this answer is getting big as it is):

#declare pos1=array[2]{-1,0}; //the corners' coordinates
#declare pos2=array[2]{1,0};
#declare pos3=array[2]{0,1};
#declare cyl_rad=0.5;

#declare pol1=polygon{3,<pos1[0],pos1[1],0> <pos2[0],pos2[1],0> <pos3[0],pos3[1],0>} //Declare the polygon
#declare cyl1=cylinder{<pos1[0],pos1[1],-0.01> <pos1[0],pos1[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the first corner
#declare cyl2=cylinder{<pos2[0],pos2[1],-0.01> <pos2[0],pos2[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the second corner
#declare cyl3=cylinder{<pos3[0],pos3[1],-0.01> <pos3[0],pos3[1],0.01>,cyl_rad} //Declare the cylinder that will "replace" the third corner
difference{polygon{pol1} cyl1 cyl2 cyl3 pigment {color_part}} //The polygon with its corners "cut"
intersection{polygon{pol1} cyl3 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,0,1>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos3[0],pos3[1],0>} } //Replacing the corners with the coloured cylinders
intersection{polygon{pol1} cyl2 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,1,1>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos2[0],pos2[1],0>} }
intersection{polygon{pol1} cyl1 pigment{spherical color_map{[0.0 rgb <1,0,0>] [0.95 rgb <0,1,0>]} scale<cyl_rad,cyl_rad,cyl_rad> translate <pos1[0],pos1[1],0>} }


问:
passing php variable into html
I'm new to php so pardon the ignorance

I'm trying to include a php variable, it is and is not working.

```<code>$currentdata = file_get_contents("http://www.abr.business.gov.au/abnDetails.aspx?abn=$abn");
</code>```

This works with $abn being the variable being passed from earlier being set.

```<code>$abntypedata = '/d$abn&ResultListURL=">(.+?)</'; This does not work.
$abntypedata = '/d33051775556&ResultListURL=">(.+?)</'; This does.
</code>```

I need to be able to use the variable $abn to insert that number as it will be user defined. Why is this not working?

答:
Php is perticular about the quotations. You have to use double quotes to include variables:

```<code>$abntypedata = "/d$abn&ResultListURL=\">(.+?)</"; This works
</code>```

or

```<code>$abntypedata = '/d'.$abn.'&ResultListURL=">(.+?)</'; This works
</code>```

ContentLicense: CC BY-SA 3.0

Title: passing php variable into html

Body:
I'm new to php so pardon the ignorance

I'm trying to include a php variable, it is and is not working.

$currentdata = file_get_contents("http://www.abr.business.gov.au/abnDetails.aspx?abn=$abn");

This works with $abn being the variable being passed from earlier being set.

$abntypedata = '/d$abn&ResultListURL=">(.+?)</'; This does not work.
$abntypedata = '/d33051775556&ResultListURL=">(.+?)</'; This does.

I need to be able to use the variable $abn to insert that number as it will be user defined. Why is this not working?

Body:
Php is perticular about the quotations. You have to use double quotes to include variables:

$abntypedata = "/d$abn&amp;ResultListURL=\">(.+?)</"; This works

or

$abntypedata = '/d'.$abn.'&amp;ResultListURL=">(.+?)</'; This works


问:
How to change classnames of list elements
I have a component, that a list of items.

```<code>render() {
    const { clickHandler } = this.props;
return (
    <section className="container birds-list">
        <ul className="birds-list__list">
            {this.props.list.map(({name, id}) => (
                <li key={id} className="birds-list__item">
                    <div className="shape shape-default"></div>
                    <div onClick={clickHandler} className="birds-list__item-name">{name}</div>
                </li>
            )
            )}
        </ul>
    </section>
</code>```

In clickHandler function I change background color of div with shape class name like e.target.previousSibling.classList.add('shape-complete');

But when I want to rerender my component with new names, I want to change all div elements with default class names with 'shape shape-default' instead of it I have div elements with classes, that I added ('shape shape-default shape-complete')

答:
You've mutated the DOM outside of React. You should instead control your classnames within "Reactland". A method for achieving this is to maintain a map or some data structure in state of "selected" or "clicked" elements to which a classname is applied (think similar to a checkbox being checked).

```<code>state = {
  clicked: {},
};

const clickHandler = id => this.setState(prevState => {
  const newClicked = {...prevState.clicked};
  newClicked[id] = !newClicked[id];
  return newClicked;
});

render() {
  ...
  this.props.list.map(({name, id}) => {
    const classNames = ['shape shape-default'];
    if (this.state.checked[id] classNames.push('shape-complete');

    return (
      <li key={id} className="birds-list__item">
        <div className={classNames.join(' ')}></div>
        <div onClick={clickHandler} className="birds-list__item-name">{name}</div>
      </li>
    )
  })
  ...
</code>```

Using the classnames npm package simplifies this a bit

```<code>import classNames from 'classnames';
...

state = {
  clicked: {},
};

const clickHandler = id => this.setState(prevState => {
  const newClicked = {...prevState.clicked};
  newClicked[id] = !newClicked[id];
  return newClicked;
});

render() {
  ...
  this.props.list.map(({name, id}) => {
    const classnames = classNames(
      'shape',
      'shape-default',
      {
        'shape-complete': this.state.checked[id],
      },
    );

    return (
      <li key={id} className="birds-list__item">
        <div className={classnames}></div>
        <div onClick={clickHandler} className="birds-list__item-name">{name}</div>
      </li>
    )
  })
  ...
</code>```

Body:
I have a component, that a list of items.

render() {
    const { clickHandler } = this.props;
return (

            {this.props.list.map(({name, id}) => (

{name}

            )
            )}

In clickHandler function I change background color of div with shape class name like e.target.previousSibling.classList.add('shape-complete');

But when I want to rerender my component with new names, I want to change all div elements with default class names with 'shape shape-default' instead of it I have div elements with classes, that I added ('shape shape-default shape-complete')

Body:
You've mutated the DOM outside of React. You should instead control your classnames within "Reactland". A method for achieving this is to maintain a map or some data structure in state of "selected" or "clicked" elements to which a classname is applied (think similar to a checkbox being checked).

state = {
  clicked: {},
};

const clickHandler = id => this.setState(prevState => {
  const newClicked = {...prevState.clicked};
  newClicked[id] = !newClicked[id];
  return newClicked;
});

render() {
  ...
  this.props.list.map(({name, id}) => {
    const classNames = ['shape shape-default'];
    if (this.state.checked[id] classNames.push('shape-complete');

    return (
      <li key={id} className="birds-list__item">
        <div className={classNames.join(' ')}></div>
        <div onClick={clickHandler} className="birds-list__item-name">{name}</div>
      </li>
    )
  })
  ...

Using the classnames npm package simplifies this a bit

import classNames from 'classnames';
...

state = {
  clicked: {},
};

const clickHandler = id => this.setState(prevState => {
  const newClicked = {...prevState.clicked};
  newClicked[id] = !newClicked[id];
  return newClicked;
});

render() {
  ...
  this.props.list.map(({name, id}) => {
    const classnames = classNames(
      'shape',
      'shape-default',
      {
        'shape-complete': this.state.checked[id],
      },
    );

    return (
      <li key={id} className="birds-list__item">
        <div className={classnames}></div>
        <div onClick={clickHandler} className="birds-list__item-name">{name}</div>
      </li>
    )
  })
  ...


问:
Using colormap to create a PIL Image from the luminosity map of an image
I have M vectors containing 4096 data points between 0 and 1 that represent the luminosity map of faces. This is a sample of the actual images.

Now, my purpose is to put them in a plotly visual, but to do so I need to provide a PIL object representing the image, This is my MVC

```<code>import PIL.Image as pilim
import matplotlib.cm as cm
import numpy as np

greys = cm.get_cmap('Greys')
num_images = 10
num_faces = faces.shape[0]
sample_images = np.random.choice(num_faces, num_images, replace=False)

for index in sample_images:
     greyscale = np.apply_along_axis(greys, 0, faces[index]).reshape((64, 64, 4))
     im = pilim.fromarray(greyscale, mode='RGBA')
     im.save('test{}.png'.format(index))    greys = cm.get_cmap('Greys')
</code>```

Faces is a ndarray with 698 samples. Something like the following sample

```<code>[[0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]]
</code>```

and this is my depressing result

答:
PIL works with pixel data, so each of RGBA is a value from 0 to 255. A colormap default generates its RGBA values in the range 0-1. To convert them, you could multiply those by 255 and convert to 8 bit unsigned integers (uint8), like so:

```<code>greyscale = np.uint8(cmap(faces[index].reshape(64,64)) * 255)
</code>```

But, matplotlib's colormaps also support a parameter to directly generate those bytes:

```<code>greyscale = cmap(faces[index].reshape(64,64), bytes=True)
</code>```

You could reshape your arrays afterwards to (64,64,4), but it is easier and more readable to do the conversion before applying the colormap.

There is a choice of several sequential colormaps for this type of images. Appending an _r to the name gives the reverse colormap (so dark and light reversed).

Here is some code to get you started:

```<code>import PIL.Image as pilim
import matplotlib.cm as cm
import numpy as np
from matplotlib import pyplot as plt

cmap = cm.get_cmap('copper_r') # 'bone_r', 'Greys', 'copper_r', 'Purple', ...
num_images = 1

faces = np.tile(np.linspace(0,1,4096), 698).reshape(698, 4096)

num_faces = faces.shape[0]
sample_images = np.random.choice(num_faces, num_images, replace=False)
print(sample_images)
for index in sample_images:
     greyscale = cmap(faces[index].reshape(64,64), bytes=True)
     im = pilim.fromarray(greyscale, mode='RGBA')
     im.save(f'test{index}.png')
</code>```

PS: There is also an imsave function in matplotlib, which would further simplify the code:

for index in sample_images:
     plt.imsave(f'test{index}.png', faces[index].reshape(64,64), cmap=cmap)
```

If the image would show up upside down, adding origin='lower' to imsave would reverse it.

Body:
I have M vectors containing 4096 data points between 0 and 1 that represent the luminosity map of faces. This is a sample of the actual images.

Now, my purpose is to put them in a plotly visual, but to do so I need to provide a PIL object representing the image, This is my MVC

import PIL.Image as pilim
import matplotlib.cm as cm
import numpy as np

greys = cm.get_cmap('Greys')
num_images = 10
num_faces = faces.shape[0]
sample_images = np.random.choice(num_faces, num_images, replace=False)

for index in sample_images:
     greyscale = np.apply_along_axis(greys, 0, faces[index]).reshape((64, 64, 4))
     im = pilim.fromarray(greyscale, mode='RGBA')
     im.save('test{}.png'.format(index))    greys = cm.get_cmap('Greys')

Faces is a ndarray with 698 samples. Something like the following sample

[[0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]
 [0.01617647 0.01617647 0.01617647 ... 0.         0.         0.        ]]

and this is my depressing result

Body:
PIL works with pixel data, so each of RGBA is a value from 0 to 255. A colormap default generates its RGBA values in the range 0-1. To convert them, you could multiply those by 255 and convert to 8 bit unsigned integers (uint8), like so:

greyscale = np.uint8(cmap(faces[index].reshape(64,64)) * 255)

But, matplotlib's colormaps also support a parameter to directly generate those bytes:

greyscale = cmap(faces[index].reshape(64,64), bytes=True)

You could reshape your arrays afterwards to (64,64,4), but it is easier and more readable to do the conversion before applying the colormap.

There is a choice of several sequential colormaps for this type of images. Appending an _r to the name gives the reverse colormap (so dark and light reversed).

Here is some code to get you started:

import PIL.Image as pilim
import matplotlib.cm as cm
import numpy as np
from matplotlib import pyplot as plt

cmap = cm.get_cmap('copper_r') # 'bone_r', 'Greys', 'copper_r', 'Purple', ...
num_images = 1

faces = np.tile(np.linspace(0,1,4096), 698).reshape(698, 4096)

num_faces = faces.shape[0]
sample_images = np.random.choice(num_faces, num_images, replace=False)
print(sample_images)
for index in sample_images:
     greyscale = cmap(faces[index].reshape(64,64), bytes=True)
     im = pilim.fromarray(greyscale, mode='RGBA')
     im.save(f'test{index}.png')

PS: There is also an imsave function in matplotlib, which would further simplify the code:

for index in sample_images:
     plt.imsave(f'test{index}.png', faces[index].reshape(64,64), cmap=cmap)

If the image would show up upside down, adding origin='lower' to imsave would reverse it.


问:
How to join multiple rows sequentially in a numpy array?
I've a data like this,

```<code>data = [array(['a', 'b', 'c']),
        array([['d', 'e', 'f'], ['g', 'h', 'i']]),
        array([['j', 'k', 'l'], ['m', 'n', 'o'], ['p', 'q', 'r']])]
</code>```

I want to join values in inner list sequentially. This is the desired output that I need.

```<code>[['a', 'b', 'c'], ['d g', 'e h', 'f i'], ['j m p', 'k n q', 'l o r']]
</code>```

I tried using using multiple loops and join but it's not giving me required output.

```<code>for i in data:
    for j in i:
        print(" ".join(j))
</code>```

I'm not really sure on how to achieve this? Need an efficient and faster approach because my original data is really large.

答:
Since you say there are also timestamp values, I cast to string for every sub-array.</p>

```<code>out = [[' '.join(tup) for tup in zip(*arr.astype(str))] if arr.ndim > 1 else arr.tolist()
               for arr in data]

Out[89]: [['a', 'b', 'c'], ['d g', 'e h', 'f i'], ['j m p', 'k n q', 'l o r']]
</code>```

Body:
I've a data like this,

data = [array(['a', 'b', 'c']),
        array([['d', 'e', 'f'], ['g', 'h', 'i']]),
        array([['j', 'k', 'l'], ['m', 'n', 'o'], ['p', 'q', 'r']])]

I want to join values in inner list sequentially. This is the desired output that I need.

[['a', 'b', 'c'], ['d g', 'e h', 'f i'], ['j m p', 'k n q', 'l o r']]

I tried using using multiple loops and join but it's not giving me required output.

for i in data:
    for j in i:
        print(" ".join(j))

I'm not really sure on how to achieve this? Need an efficient and faster approach because my original data is really large.

Body:
Since you say there are also timestamp values, I cast to string for every sub-array.

out = [[' '.join(tup) for tup in zip(*arr.astype(str))] if arr.ndim > 1 else arr.tolist()
               for arr in data]

Out[89]: [['a', 'b', 'c'], ['d g', 'e h', 'f i'], ['j m p', 'k n q', 'l o r']]


问:
How SSH Environment Variables works with shell script file?
If I run the command bellow and my install.sh has the following section:

```<code>export S3_URL=$PRD_URL
export S3_ACCESS_KEY=$PRD_S3_ACCESS_KEY
export S3_SECRET_KEY=$PRD_S3_SECRET_KEY
</code>```

cat install.sh | ssh $PRD_USER@$PRD_HOST

The $PRD_S3_ACCESS_KEY is going to be resolved from my host or the environment variables from the remote server?

答:
Assuming you have gettext installed (which contains envsubst), you can do

```<code>envsubst < install.sh | ssh $PRD_USER@$PRD_HOST
</code>```

Body:
If I run the command bellow and my install.sh has the following section:

export S3_URL=$PRD_URL
export S3_ACCESS_KEY=$PRD_S3_ACCESS_KEY
export S3_SECRET_KEY=$PRD_S3_SECRET_KEY

cat install.sh | ssh $PRD_USER@$PRD_HOST

The $PRD_S3_ACCESS_KEY is going to be resolved from my host or the environment variables from the remote server?

Body:
Assuming you have gettext installed (which contains envsubst), you can do

envsubst < install.sh | ssh $PRD_USER@$PRD_HOST


问:
Don't understand iterator, reference and pointer invalidation, an example
I've read a lot of posts abut reference, pointers and iterators invalidation. For instance I've read that insertion invalidates all reference to the elements of a deque, then why in the following code I don't have errors?

```<code>#include <deque>

int main()
{
    std::deque<int> v1 = { 1, 3, 4, 5, 7, 8, 9, 1, 3, 4 };
    int& a = v1[6];
    std::deque<int>::iterator it = v1.insert(v1.begin() + 2, 3);
    int c = a;
    return a;
}
</code>```

When I run this I get 9 as result, so "a" is still referring to the right element.
In general I didn't manage to get invalidation errors. I tried different containers and even with pointers and iterators.

答:
The following code, on my system, shows the effect of the undefined behavior.

```<code>#include <deque>
#include <iostream>

int main()
{
    std::deque<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    for (auto e : v1) std::cout << e << ' ';
    std::cout << std::endl;
    int& a = v1[1];
    int& b = v1[2];
    int& c = v1[3];
    std::cout << a << ' ' << b << ' ' << c << std::endl;
    std::deque<int>::iterator it = v1.insert(v1.begin() + 2, -1);
    for (auto e : v1) std::cout << e << ' ';
    std::cout << std::endl;
    v1[7] = -3;
    std::cout << a << ' ' << b << ' ' << c << std::endl;
    return a;
}
</code>```

Its output for me is:

```<code>1 2 3 4 5 6 7 8 9 10
2 3 4
1 2 -1 3 4 5 6 7 8 9 10
-1 3 4
</code>```

If the references a, b, and c, were still valid, the last line should have been

```<code>2 3 4
</code>```

Please, do not deduce from this that a has been invalidated while b and c are still valid. They're all invalid.

Try it out, maybe you are "lucky" and it shows the same to you. If it doesn't, play around with the number of elements in the containar and a few insertions. At some point maybe you'll see something strange as in my case.

Addendum

The ways std::deques can be implemented all makes the invalidation mechanism a bit more complex than what happens for the "simpler" std::vector. And you also have less ways to check if something is actually going to suffer from the effect of undefined behavior. With std::vector, for instance, you can tell if undefined behavior will sting you upon a push_back; indeed, you have the member function capacity, which tells if the container has already enough space to accomodate a bigger size required by the insertion of further elements by means of push_back. For instance if size gives 8, and capacity gives 10, you can push_back two more elements "safely". If you push one more, the array will have to be reallocated.

Body:
I've read a lot of posts abut reference, pointers and iterators invalidation. For instance I've read that insertion invalidates all reference to the elements of a deque, then why in the following code I don't have errors?

#include <deque>

int main()
{
    std::deque<int> v1 = { 1, 3, 4, 5, 7, 8, 9, 1, 3, 4 };
    int& a = v1[6];
    std::deque<int>::iterator it = v1.insert(v1.begin() + 2, 3);
    int c = a;
    return a;
}

When I run this I get 9 as result, so "a" is still referring to the right element.
In general I didn't manage to get invalidation errors. I tried different containers and even with pointers and iterators.

Body:
The following code, on my system, shows the effect of the undefined behavior.

#include <deque>
#include <iostream>

int main()
{
    std::deque<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    for (auto e : v1) std::cout << e << ' ';
    std::cout << std::endl;
    int& a = v1[1];
    int& b = v1[2];
    int& c = v1[3];
    std::cout << a << ' ' << b << ' ' << c << std::endl;
    std::deque<int>::iterator it = v1.insert(v1.begin() + 2, -1);
    for (auto e : v1) std::cout << e << ' ';
    std::cout << std::endl;
    v1[7] = -3;
    std::cout << a << ' ' << b << ' ' << c << std::endl;
    return a;
}

Its output for me is:

1 2 3 4 5 6 7 8 9 10
2 3 4
1 2 -1 3 4 5 6 7 8 9 10
-1 3 4

If the references a, b, and c, were still valid, the last line should have been

2 3 4

Please, do not deduce from this that a has been invalidated while b and c are still valid. They're all invalid.

Try it out, maybe you are "lucky" and it shows the same to you. If it doesn't, play around with the number of elements in the containar and a few insertions. At some point maybe you'll see something strange as in my case.

Addendum

The ways std::deques can be implemented all makes the invalidation mechanism a bit more complex than what happens for the "simpler" std::vector. And you also have less ways to check if something is actually going to suffer from the effect of undefined behavior. With std::vector, for instance, you can tell if undefined behavior will sting you upon a push_back; indeed, you have the member function capacity, which tells if the container has already enough space to accomodate a bigger size required by the insertion of further elements by means of push_back. For instance if size gives 8, and capacity gives 10, you can push_back two more elements "safely". If you push one more, the array will have to be reallocated.


问:
Save original data filter, unfiltered and unsorted
I'm trying to save original data state to "all" filter. The content gets sorted and filtered by data attribute "data-filter". So my output will be the original state unfiltered and unsorted. Note: the divs content that have the same "data-id" will be displayed only once.

So my desired output on "all" filter and when I first run the code will be:

content first

content second

content third

content fourth

Also for
 - filter “one" the output will always be "content first",
 - filter “two” the ouput will be "content second” "content third”
…and so on

function removeDuplicates() {
  var content = $('.content');
  contentIds = content.map(function() {
    return $(this).data("id");
  }).toArray();
  var newSetContentIds = [...new Set(contentIds)];
  listedContent = $(newSetContentIds).map(function() {
    return $("[data-id=" + this + "]").first()[0];
  });

  listedContent.addClass('listed');
}

$('.filter').click(function() {

  var filterId = $(this).attr('data-filter');

  $('.content').hide();
  $('.content[data-filter=' + filterId + ']').addClass('active').show();

  removeDuplicates();
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.listed {
  display: none;
}</code>```

    all

    one

    two

    three

    content first

    content second

    content third

    content third

    content fourth

    content first

```

答:
Your removeDuplicates function is not working. Also, it hinted that you want to run this function only the first time you press any of the filters.

Instead of using show() and hide() that apply inline display messing up with the .listed class, you can use another class .hidden to show or hide the divs.

Finally, it was no clear if you want to sort once or every time when the chosen filter is not "all". Anyway, as mentioned, you can use flex property for the container and order property for the divs. It is inside removeDuplicates considering you want to sort divs once for all after the first click.

function removeDuplicates() {

    $(".filter").off("click", removeDuplicates);

    var content = $('.content');
    contentIds = content.map(function() {
        $(this).css('order', $(this).data("filter"));
        return $(this).data("id");
    }).toArray();

    var newContentIds = contentIds.filter((a, i, aa) => aa.indexOf(a) === i && aa.lastIndexOf(a) !== i);
    listedContent = $(newContentIds).map(function() {
        return $("[data-id=" + this + "]")[0];
    });

    listedContent.addClass('listed');
}

$(".filter").on("click", removeDuplicates);

$('.filter').click(function() {

    var filterId = $(this).attr('data-filter');

    if (filterId == "all") {
        $('.content').removeClass('hidden');
        return;
    }

    $('.content').addClass('hidden');
    $('.content[data-filter=' + filterId + ']').addClass('active').removeClass('hidden');
});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.hidden {
  display: none;
}

.content.listed {
  display: none;
}

.content-container {
  display: flex;
  flex-direction: column;
}</code>```

    all

    one

    two

    three

    content first

    content second

    content third

    content third

    content fourth

    content first

```

Body:
I'm trying to save original data state to "all" filter. The content gets sorted and filtered by data attribute "data-filter". So my output will be the original state unfiltered and unsorted. Note: the divs content that have the same "data-id" will be displayed only once.

So my desired output on "all" filter and when I first run the code will be:

content first

content second

content third

content fourth

Also for
 - filter “one" the output will always be "content first",
 - filter “two” the ouput will be "content second” "content third”
…and so on

function removeDuplicates() {
  var content = $('.content');
  contentIds = content.map(function() {
    return $(this).data("id");
  }).toArray();
  var newSetContentIds = [...new Set(contentIds)];
  listedContent = $(newSetContentIds).map(function() {
    return $("[data-id=" + this + "]").first()[0];
  });

  listedContent.addClass('listed');
}

$('.filter').click(function() {

  var filterId = $(this).attr('data-filter');

  $('.content').hide();
  $('.content[data-filter=' + filterId + ']').addClass('active').show();

  removeDuplicates();
});

.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.listed {
  display: none;
}

    all

    one

    two

    three

    content first

    content second

    content third

    content third

    content fourth

    content first

Body:
Your removeDuplicates function is not working. Also, it hinted that you want to run this function only the first time you press any of the filters.

Instead of using show() and hide() that apply inline display messing up with the .listed class, you can use another class .hidden to show or hide the divs.

Finally, it was no clear if you want to sort once or every time when the chosen filter is not "all". Anyway, as mentioned, you can use flex property for the container and order property for the divs. It is inside removeDuplicates considering you want to sort divs once for all after the first click.

function removeDuplicates() {

    $(".filter").off("click", removeDuplicates);

    var content = $('.content');
    contentIds = content.map(function() {
        $(this).css('order', $(this).data("filter"));
        return $(this).data("id");
    }).toArray();

    var newContentIds = contentIds.filter((a, i, aa) => aa.indexOf(a) === i && aa.lastIndexOf(a) !== i);
    listedContent = $(newContentIds).map(function() {
        return $("[data-id=" + this + "]")[0];
    });

    listedContent.addClass('listed');
}

$(".filter").on("click", removeDuplicates);

$('.filter').click(function() {

    var filterId = $(this).attr('data-filter');

    if (filterId == "all") {
        $('.content').removeClass('hidden');
        return;
    }

    $('.content').addClass('hidden');
    $('.content[data-filter=' + filterId + ']').addClass('active').removeClass('hidden');
});

.filter-container {
  display: flex;
}

.filter-container div {
  margin: 10px;
  cursor: pointer;
}

.hidden {
  display: none;
}

.content.listed {
  display: none;
}

.content-container {
  display: flex;
  flex-direction: column;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="filter-container">
  <div class="filter" data-filter="all">
    all
  </div>
  <div class="filter" data-filter="1">
    one
  </div>
  <div class="filter" data-filter="2">
    two
  </div>
  <div class="filter" data-filter="3">
    three
  </div>
</div>

<div class="content-container">
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
  <div class="content" data-filter="2" data-id="15">
    content second
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="2" data-id="17">
    content third
  </div>
  <div class="content" data-filter="3" data-id="16">
    content fourth
  </div>
  <div class="content" data-filter="1" data-id="20">
    content first
  </div>
</div>


答:
Try adding Double Quotes around the string " not ' that should render the variables other wise do this:</p>

```<code>$abntypedata = '/d'.$abn.'&ResultListURL=">(.+?)</';
</code>```

Title: passing php variable into html

Body:
Try adding Double Quotes around the string " not ' that should render the variables other wise do this:

$abntypedata = '/d'.$abn.'&amp;ResultListURL=">(.+?)</';


答:
The solution is actually pretty simple. There are two steps missing on my code:

re-scale to 0-255 values

Cast to uint8 in order to PIL to understand the array

greyscale = np.apply_along_axis(greys, 0, faces[index]).reshape((64, 64, 4))*255
greyscale = greyscale.astype(np.uint8)
im = pilim.fromarray(greyscale)

https://python-decompiler.com/article/2012-06/how-to-convert-numpy-array-to-pil-image-applying-matplotlib-colormap

Title: Using colormap to create a PIL Image from the luminosity map of an image


问:
Parsing XML: Math Equations - SVG Example
I would like to pick out the positions and font sizes of each of the symbols used in an SVG of a mathematical equation.

I am playing around with the Python XML parsing library: xml.etree.ElementTree (https://docs.python.org/3/library/xml.etree.elementtree.html).

Here is the example SVG I am using:

```<code>example_svg = '''<svg style="vertical-align:-10.2252022445128pt" xmlns="http://www.w3.org/2000/svg" width="193pt" height="31pt" viewBox="-1 -1 193 31">
<path d="M43.875 16.305h20.426" fill="none" stroke-width=".914" stroke="#000" stroke-miterlimit="10"></path>
<g font-family="MathFont" font-size="13.5">
<text y="11.168" x="45.874">3</text>
<text y="11.168" x="52.532"></text>
<text y="28.382" x="50.758">4</text>
</g>
<g font-family="MathFont" font-size="9.45">
<text y="6.327" x="60.453">3</text></g>
</svg>'''
</code>```

In Latex the equation is $\frac{3x^3}{4}$.

Using the following code gives me nearly everything I want, but I can’t seem to connect this to the attributes in group text. Ideally I want the output to be (symbol, y_coord, x_coord, font-family, font-size).

```<code>import xml.etree.ElementTree as ET

root = ET.fromstring(example_svg)

for tag in root.findall('.//{http://www.w3.org/2000/svg}text'):
  symbol = tag.text
  y_coord = tag.get('y')
  x_coord = tag.get('x')
  print(symbol, y_coord, x_coord)
</code>```

答:
The font family name and size are not specified in <text> elements but in their parent <g> groups. Some care is necessary, because multiple <g> elements may appear nested in each other.

You can locate all <g> elements with find_all and temporarily store the font parameters, but if you try to do so to first find <g> and then its <text>s, you will soon notice it cannot properly handle nested groups. Every occurrence of <g> will trigger looking for its contained <text> elements, and so if there is a set of nested

<g group parameters>
    <g text parameters>
        <text>your text</text>
    </g>
</g>

then it will report all <text> elements twice: once for each (nested or not) <g>.

A better way, then, is to iterate over the entire XML file and storing the font information as and when you come along it.

root = ET.fromstring(example_svg)

font = None
font_size = None
for elem in root.iter():
    if elem.tag == '{http://www.w3.org/2000/svg}g':
        item = elem.get('font-family')
        if item is not None:
            font = item
        item = elem.get('font-size')
        if item is not None:
            font_size = item

    elif elem.tag == '{http://www.w3.org/2000/svg}text':
        symbol = elem.text
        y_coord = elem.get('y')
        x_coord = elem.get('x')
        print (symbol, y_coord, x_coord, font, font_size)
```

<p>(Note that <code>iter()</code> needs the full SVG namespace prepended to each element.)</p>

<p>Result:</p>

<pre class="lang-none prettyprint-override"><code>3 11.168 45.874 MathFont 13.5
 11.168 52.532 MathFont 13.5
4 28.382 50.758 MathFont 13.5
3 6.327 60.453 MathFont 9.45
</code>```

Body:
I would like to pick out the positions and font sizes of each of the symbols used in an SVG of a mathematical equation.

I am playing around with the Python XML parsing library: xml.etree.ElementTree (https://docs.python.org/3/library/xml.etree.elementtree.html).

Here is the example SVG I am using:

example_svg = '''<svg style="vertical-align:-10.2252022445128pt" xmlns="http://www.w3.org/2000/svg" width="193pt" height="31pt" viewBox="-1 -1 193 31">
<path d="M43.875 16.305h20.426" fill="none" stroke-width=".914" stroke="#000" stroke-miterlimit="10"></path>
<g font-family="MathFont" font-size="13.5">
<text y="11.168" x="45.874">3</text>
<text y="11.168" x="52.532"></text>
<text y="28.382" x="50.758">4</text>
</g>
<g font-family="MathFont" font-size="9.45">
<text y="6.327" x="60.453">3</text></g>
</svg>'''

In Latex the equation is $\frac{3x^3}{4}$.

Using the following code gives me nearly everything I want, but I can’t seem to connect this to the attributes in group text. Ideally I want the output to be (symbol, y_coord, x_coord, font-family, font-size).

import xml.etree.ElementTree as ET

root = ET.fromstring(example_svg)

for tag in root.findall('.//{http://www.w3.org/2000/svg}text'):
  symbol = tag.text
  y_coord = tag.get('y')
  x_coord = tag.get('x')
  print(symbol, y_coord, x_coord)

Body:
The font family name and size are not specified in <text> elements but in their parent <g> groups. Some care is necessary, because multiple <g> elements may appear nested in each other.

You can locate all <g> elements with find_all and temporarily store the font parameters, but if you try to do so to first find <g> and then its <text>s, you will soon notice it cannot properly handle nested groups. Every occurrence of <g> will trigger looking for its contained <text> elements, and so if there is a set of nested

<g group parameters>
    <g text parameters>
        <text>your text</text>
    </g>
</g>

then it will report all <text> elements twice: once for each (nested or not) <g>.

A better way, then, is to iterate over the entire XML file and storing the font information as and when you come along it.

root = ET.fromstring(example_svg)

font = None
font_size = None
for elem in root.iter():
    if elem.tag == '{http://www.w3.org/2000/svg}g':
        item = elem.get('font-family')
        if item is not None:
            font = item
        item = elem.get('font-size')
        if item is not None:
            font_size = item

    elif elem.tag == '{http://www.w3.org/2000/svg}text':
        symbol = elem.text
        y_coord = elem.get('y')
        x_coord = elem.get('x')
        print (symbol, y_coord, x_coord, font, font_size)

(Note that iter() needs the full SVG namespace prepended to each element.)

Result:

3 11.168 45.874 MathFont 13.5
 11.168 52.532 MathFont 13.5
4 28.382 50.758 MathFont 13.5
3 6.327 60.453 MathFont 9.45


问:
Google Analytics Event not firing containing hit type
I've got a small little internal app that counts code, and I'm trying to set it up so that Google Analytics logs an event everytime somebody uses it, but the problem is, the event isn't logging. I've got my google analytics tag in my head, but when I call the following function:

```<code>ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);
</code>```

Once my ajax call to actually count the code has completed, nothing happens. There is no event logged in Google Analytics.

What am I doing wrong?

--------------------- EDIT ---------------------

Here is the surrounding code where it is called:

```<code>window.addEventListener("repofound", (ev:CustomEvent) => {

    const repoUrl:string = ev.detail;
    const ajax:XMLHttpRequest = new XMLHttpRequest();
    ajax.open("GET", "https://URLtoServer" + repoUrl);
    ajax.send();
    ajax.onload = () => {

        countButton.removeAttribute("aria-busy");

        const jsonReturn = JSON.parse(ajax.response);

        if (jsonReturn.success) {

            ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);

            // specific client side UI code that is most definitely firing

        }

    };

}, false);
</code>```

答:
From your comment it is clear that you are using the gtag library while the event is sending it with ga (Analytics Universal).

So you need to edit your event from this:

```<code>ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);
</code>```

To this:

```<code>gtag('event', 'counted', {
  'event_category': 'code',
  'event_label': 'Counted Code',
  'value': jsonReturn.data.raw_total
});
</code>```

Body:
I've got a small little internal app that counts code, and I'm trying to set it up so that Google Analytics logs an event everytime somebody uses it, but the problem is, the event isn't logging. I've got my google analytics tag in my head, but when I call the following function:

ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);

Once my ajax call to actually count the code has completed, nothing happens. There is no event logged in Google Analytics.

What am I doing wrong?

--------------------- EDIT ---------------------

Here is the surrounding code where it is called:

window.addEventListener("repofound", (ev:CustomEvent) => {

    const repoUrl:string = ev.detail;
    const ajax:XMLHttpRequest = new XMLHttpRequest();
    ajax.open("GET", "https://URLtoServer" + repoUrl);
    ajax.send();
    ajax.onload = () => {

        countButton.removeAttribute("aria-busy");

        const jsonReturn = JSON.parse(ajax.response);

        if (jsonReturn.success) {

            ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);

            // specific client side UI code that is most definitely firing

        }

    };

}, false);

Body:
From your comment it is clear that you are using the gtag library while the event is sending it with ga (Analytics Universal).

So you need to edit your event from this:

ga("send", "event", "code", "counted", "Counted Code", jsonReturn.data.raw_total);

To this:

gtag('event', 'counted', {
  'event_category': 'code',
  'event_label': 'Counted Code',
  'value': jsonReturn.data.raw_total
});


问:
How can you change to color of the text in Flutter
So, Im new to flutter and wanted to see how can you change the color of the text.

```<code>import 'package:flutter/material.dart';

void main() => runApp(new Hello());

class Hello extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Material(
        child: new Center(
          child: new Text("Hello!"),
        ),
      ),
    );
  }
}
</code>```

this is a basic hello text and I want the text to be other color than the standard.

答:
This can be easily achieved by style function. Which will take the TextStyle parameter, where you can specify color. You can use a Material set of colors, like red, yellow, green, blue, black, transparent, etc. Or you can specify by its HEX color code, like this: TextStyle(color: Color(0xff**000000**)). The HEX color always starts with 0xff followed by the six-digit number of the color.

```<code>import 'package:flutter/material.dart';

void main() => runApp(new Hello());

class Hello extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Material(
        child: new Center(
          child: new Text("Hello!", style: TextStyle(color: Colors.indigo)),
        ),
      ),
    );
  }
}
</code>```

Also, with material colors you can give them different shades by specifying their opacity, like TextStyle(color: Colors.green[600])

Body:
So, Im new to flutter and wanted to see how can you change the color of the text.

import 'package:flutter/material.dart';

void main() => runApp(new Hello());

class Hello extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Material(
        child: new Center(
          child: new Text("Hello!"),
        ),
      ),
    );
  }
}

this is a basic hello text and I want the text to be other color than the standard.

Body:
This can be easily achieved by style function. Which will take the TextStyle parameter, where you can specify color. You can use a Material set of colors, like red, yellow, green, blue, black, transparent, etc. Or you can specify by its HEX color code, like this: TextStyle(color: Color(0xff**000000**)). The HEX color always starts with 0xff followed by the six-digit number of the color.

import 'package:flutter/material.dart';

void main() => runApp(new Hello());

class Hello extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Material(
        child: new Center(
          child: new Text("Hello!", style: TextStyle(color: Colors.indigo)),
        ),
      ),
    );
  }
}

Also, with material colors you can give them different shades by specifying their opacity, like TextStyle(color: Colors.green[600])


问:
Selenium: Trying to get Firefox console logs results in "WebDriverError: HTTP method not allowed"
I'm trying to capture console errors in my selenium tests (node environment with selenium-webdriver 4.0.0-alpha.5 and the latest geckodriver and chromedriver). I've set up one driver for Firefox and another one for Chrome like this:

const chrome = require('selenium-webdriver/chrome');
const firefox = require('selenium-webdriver/firefox');
const webdriver = require('selenium-webdriver');
const { Builder, By, Capabilities, until } = webdriver;

let loggingPref = new webdriver.logging.Preferences();
loggingPref.setLevel( 'browser', webdriver.logging.Level.SEVERE );

let driver_fx = await new Builder()
  .withCapabilities(
    Capabilities.firefox()
    .set("acceptInsecureCerts", true)
  )
  .setLoggingPrefs( loggingPref )
  .build();

let driver_chr = await new Builder()
  .forBrowser('chrome')
  .setLoggingPrefs( loggingPref )
  .build();
```

<p>This is the function that should get the error logs:</p>

<pre class="lang-js prettyprint-override"><code>const getConsoleErrors = (driver) => {
  return driver.manage().logs().get('browser').then((logs) => {
    return logs.map(( log ) => log.message );
  });
}
</code>```

With the chrome driver, this works as intended:

await driver.get(devUrl);

let errors = await getConsoleErrors(driver_chr);
console.log(errors);
// output:
// [ 'https://mylocaldevserver/with/path 465:61 Uncaught TypeError: Cannot read property \'textContent\' of null' ]
```

However, when passing driver_fx to the function instead, this results in the following exception:

WebDriverError: HTTP method not allowed

     at parseHttpResponse (***\node_modules\selenium-webdriver\lib\http.js:580:11)

     at Executor.execute (***\node_modules\selenium-webdriver\lib\http.js:489:26)

     at process._tickCallback (internal/process/next_tick.js:68:7)

Is this a bug in selenium or geckodriver, or is it the way I construct the Firefox driver differently (which I need to do for it to ignore the certificate of my local dev server)?

答:
For future googlers, unfortunately log('browser') is not in W3C specification, hence the geckodriver team seems to be stalling it. There is no official "fix" for it as of today (Feb 17 2020).

You'll most likely have to use a work around like: https://github.com/mozilla/geckodriver/issues/284#issuecomment-477677764

Find more information here: https://github.com/mozilla/geckodriver/issues/284

Body:
I'm trying to capture console errors in my selenium tests (node environment with selenium-webdriver 4.0.0-alpha.5 and the latest geckodriver and chromedriver). I've set up one driver for Firefox and another one for Chrome like this:

const chrome = require('selenium-webdriver/chrome');
const firefox = require('selenium-webdriver/firefox');
const webdriver = require('selenium-webdriver');
const { Builder, By, Capabilities, until } = webdriver;

let loggingPref = new webdriver.logging.Preferences();
loggingPref.setLevel( 'browser', webdriver.logging.Level.SEVERE );

let driver_fx = await new Builder()
  .withCapabilities(
    Capabilities.firefox()
    .set("acceptInsecureCerts", true)
  )
  .setLoggingPrefs( loggingPref )
  .build();

let driver_chr = await new Builder()
  .forBrowser('chrome')
  .setLoggingPrefs( loggingPref )
  .build();

This is the function that should get the error logs:

const getConsoleErrors = (driver) => {
  return driver.manage().logs().get('browser').then((logs) => {
    return logs.map(( log ) => log.message );
  });
}

With the chrome driver, this works as intended:

await driver.get(devUrl);

let errors = await getConsoleErrors(driver_chr);
console.log(errors);
// output:
// [ 'https://mylocaldevserver/with/path 465:61 Uncaught TypeError: Cannot read property \'textContent\' of null' ]

However, when passing driver_fx to the function instead, this results in the following exception:

WebDriverError: HTTP method not allowed

     at parseHttpResponse (***\node_modules\selenium-webdriver\lib\http.js:580:11)

     at Executor.execute (***\node_modules\selenium-webdriver\lib\http.js:489:26)

     at process._tickCallback (internal/process/next_tick.js:68:7)

Is this a bug in selenium or geckodriver, or is it the way I construct the Firefox driver differently (which I need to do for it to ignore the certificate of my local dev server)?


问:
ESP8266 unable to read data from Google Firebase
I'm trying to make an IOT app. My android side is working good so far, however my ESP8266 is unable to read data from Firebase Database. There is no error while connecting to the internet using onboard ESP8266 though. Can anyone point to a possible error? Thank You</p>

```<code>#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>
#define WIFI_SSID "WiFi"
#define WIFI_PASSWORD "xxxxxxxx"
#define FIREBASE_HOST "https://iot.firebaseio.com"
#define FIREBASE_AUTH "xxxxxxxx"
int LED1 = D5;
void setup()
{
Serial.begin(115200);
  pinMode(LED1, OUTPUT);
  Serial.println('\n');
  wifiConnect();
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  delay(10);
}
void loop()
{
  if(WiFi.status() != WL_CONNECTED)
  {
    wifiConnect();
  }
  delay(10);
  Serial.print("Data from firebase:" + Firebase.getString("LED1") + "\n");
  digitalWrite(LED1, Firebase.getString("LED1").toInt());
  //digitalWrite(LED1, HIGH);
  delay(10);
}
void wifiConnect()
{
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);             // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID); Serial.println(" ...");

  int teller = 0;
  while (WiFi.status() != WL_CONNECTED)
  {                                       // Wait for the Wi-Fi to connect
    delay(1000);
    Serial.print(++teller); Serial.print(' ');
  }

  Serial.println('\n');
  Serial.println("Connection established!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());         // Send the IP address of the ESP8266 to the computer
}
</code>```

答: For anyone encountering this issue. I got it working by removing the forward slash '/' at the end and the https:// from the start of Host Address.</p>

Body:
I'm trying to make an IOT app. My android side is working good so far, however my ESP8266 is unable to read data from Firebase Database. There is no error while connecting to the internet using onboard ESP8266 though. Can anyone point to a possible error? Thank You

#include <ESP8266WiFi.h>
#include <FirebaseArduino.h>
#define WIFI_SSID "WiFi"
#define WIFI_PASSWORD "xxxxxxxx"
#define FIREBASE_HOST "https://iot.firebaseio.com"
#define FIREBASE_AUTH "xxxxxxxx"
int LED1 = D5;
void setup()
{
Serial.begin(115200);
  pinMode(LED1, OUTPUT);
  Serial.println('\n');
  wifiConnect();
  Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
  delay(10);
}
void loop()
{
  if(WiFi.status() != WL_CONNECTED)
  {
    wifiConnect();
  }
  delay(10);
  Serial.print("Data from firebase:" + Firebase.getString("LED1") + "\n");
  digitalWrite(LED1, Firebase.getString("LED1").toInt());
  //digitalWrite(LED1, HIGH);
  delay(10);
}
void wifiConnect()
{
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);             // Connect to the network
  Serial.print("Connecting to ");
  Serial.print(WIFI_SSID); Serial.println(" ...");

  int teller = 0;
  while (WiFi.status() != WL_CONNECTED)
  {                                       // Wait for the Wi-Fi to connect
    delay(1000);
    Serial.print(++teller); Serial.print(' ');
  }

  Serial.println('\n');
  Serial.println("Connection established!");
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());         // Send the IP address of the ESP8266 to the computer
}


问:
Customize Xamarin.Forms.Datepicker to pick and visualize multiple Dates
i'm kinda new to the whole wpf/xamarin UI thing and want to start my first mobile app.
So, like the title contains already the topic of this question, i would like to use the standard Xamarin.Forms Datepicker to let the user pick multiple Dates.

I guess it will be pretty easy to submit on the Event for picking a date and put this into an array for the selected Dates.

But how can i visualize all the selected Dates in the Datepicker Dialog? Is there any possability to do this with this Control?

Thanks :)

答:
One way to display a variable-length list of editable dates:

In your "view model" class (or whatever you use as BindingContext), maintain the list of dates as a property that is an ObservableCollection: ObservableCollection<DateTime> Dates { get; set; } = new ObservableCollection<DateTime>();

In your "view" (or "page") class, have a ListView (or the newer CollectionView), with an item template that includes a DateView picker. And Source={Binding Dates}. See https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/datepicker for an example that includes two datepickers. Except instead of explicitly putting two datepickers into your xaml, you'll put the list with its item template.

Have a button to add a new date to the list.

In item template, have a button to the right of the datepicker. Use this to remove that date, from the corresponding Dates property.

If there is a limit to how many dates you want to show, instead of having a ListView, you could manually add the maximum number of date pickers to your View or Page. Similar to the link I gave above. Then add a checkbox next to each; use that to enable/disable that date.


问:
Regexreplace function to turn multiple " \n " into a single one
How to replace consecutive newlines by one single newline in Google Sheets using regexrepleace function (or any other function).

Input: A Novus typ 4/26 C keskeny tűzőgépkapcsok alkalmasak: \n  \n  profil fa \n   panelek \n   drótháló \n   farostlemez rögzítéséhez \n   \n \n   \n    \n   \n

Output: A Novus typ 4/26 C keskeny tűzőgépkapcsok alkalmasak: \n profil fa \n panelek \n drótháló \n farostlemez rögzítéséhez \n

答:
try brute force:

```<code>=ARRAYFORMULA(TRIM(REGEXREPLACE(TRIM(SUBSTITUTE(A:A, CHAR(10), )),
 "\\n \\n \\n \\n \\n \\n|\\n \\n \\n \\n \\n|\\n \\n \\n \\n|\\n \\n \\n|\\n \\n|\\n", "\\n")))
</code>```

Body:
try brute force:

=ARRAYFORMULA(TRIM(REGEXREPLACE(TRIM(SUBSTITUTE(A:A, CHAR(10), )),
 "\\n \\n \\n \\n \\n \\n|\\n \\n \\n \\n \\n|\\n \\n \\n \\n|\\n \\n \\n|\\n \\n|\\n", "\\n")))


问:
INDIRECT from another sheet
I am trying to figure out the correct syntax to have this formula reference a different sheet.
I need =INDIRECT((ADDRESS(((COUNTA($E$5:$E$204))/2)+4,7))) to reference sheet Line 3

答:
Assuming the range $E$5:$E$204 refers to the same sheet as the one containing the formula, then you could use the Sheet_text argument of the Address function:

```<code>=INDIRECT((ADDRESS(((COUNTA($E$5:$E$204))/2)+4,7,,,"Line 3")))
</code>```

If you also want the referenced cell range to be from the Line 3 worksheet, then:

```<code>=INDIRECT((ADDRESS(((COUNTA('Line 3'!E5:E204))/2)+4,7,,,"Line 3")))
</code>```

Title: INDIRECT from another sheet

Body:
Assuming the range $E$5:$E$204 refers to the same sheet as the one containing the formula, then you could use the Sheet_text argument of the Address function:

=INDIRECT((ADDRESS(((COUNTA($E$5:$E$204))/2)+4,7,,,"Line 3")))

If you also want the referenced cell range to be from the Line 3 worksheet, then:

=INDIRECT((ADDRESS(((COUNTA('Line 3'!E5:E204))/2)+4,7,,,"Line 3")))


问:
Unboxing and inspecting a trait object
Here's a simple application that duplicates 2 times on stdout the contents of stdin:

```<code>use std::{
    io,
    io::{stdin, stdout, Read, Write},
    num::NonZeroUsize,
};

fn dup_input(
    input: &mut Box<dyn Read>,
    output: &mut Box<dyn Write>,
    count: NonZeroUsize,
) -> io::Result<()> {
    let mut buf = Vec::new();

    input.read_to_end(&mut buf)?;

    for _idx in 0..count.get() {
        output.write_all(&buf)?;
    }

    Ok(())
}

fn main() {
    let mut input: Box<dyn Read> = Box::new(stdin());
    let mut output: Box<dyn Write> = Box::new(stdout());

    dup_input(&mut input, &mut output, NonZeroUsize::new(2).unwrap())
        .expect("Failed to duplicate input");
}
</code>```

This part works fine. I want to put a unit test on top of this and this is where the problem lies. The closest I've got to build is with the following attempt:

```<code>#[cfg(test)]
mod tests {
    use super::*;
    use std::{any::Any, io::Cursor};

    #[test]
    fn test() {
        let mut input: Box<dyn Read> = Box::new(Cursor::new([b't', b'e', b's', b't', b'\n']));
        let mut output: Box<dyn Write + Any> = Box::new(Vec::<u8>::new());

        assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());

        assert_eq!(output.downcast::<Vec<u8>>().unwrap().len(), 15);
    }
}
</code>```

but rust 1.41.0 doesn't agree:

```<code>$ cargo test
   Compiling unbox-example v0.1.0 (/XXX/unbox-example)
error[E0225]: only auto traits can be used as additional traits in a trait object
  --> src/main.rs:39:41
   |
39 |         let mut output: Box<dyn Write + Any> = Box::new(Vec::<u8>::new());
   |                                 -----   ^^^
   |                                 |       |
   |                                 |       additional non-auto trait
   |                                 |       trait alias used in trait object type (additional use)
   |                                 first non-auto trait
   |                                 trait alias used in trait object type (first use)

error[E0308]: mismatched types
  --> src/main.rs:41:39
   |
41 |         assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());
   |                                       ^^^^^^^^^^^ expected trait `std::io::Write`, found a different trait `std::io::Write`
   |
   = note: expected mutable reference `&mut std::boxed::Box<(dyn std::io::Write + 'static)>`
              found mutable reference `&mut std::boxed::Box<(dyn std::io::Write + 'static)>`

error[E0599]: no method named `downcast` found for type `std::boxed::Box<(dyn std::io::Write + 'static)>` in the current scope
  --> src/main.rs:43:27
   |
43 |         assert_eq!(output.downcast::<Vec<u8>>().unwrap().len(), 15);
   |                           ^^^^^^^^ method not found in `std::boxed::Box<(dyn std::io::Write + 'static)>`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0225, E0308, E0599.
For more information about an error, try `rustc --explain E0225`.
error: could not compile `unbox-example`.

To learn more, run the command again with --verbose.
</code>```

Is there a way to change the unit test without changing the main code? Note: I could have used generics while implementing dup_input and make the problem significantly easier to solve but this code is part of a broader application and I have to use Read/Write trait objects.

答:
Passing a mutable reference to a Box to dup_input is unnecessarily complicated. You can simply pass a mutable reference to the trait object.

```<code>use std::{
    io,
    io::{stdin, stdout, Read, Write},
    num::NonZeroUsize,
};

fn dup_input(
    input: &mut dyn Read,
    output: &mut dyn Write,
    count: NonZeroUsize,
) -> io::Result<()> {
    let mut buf = Vec::new();

    input.read_to_end(&mut buf)?;

    for _idx in 0..count.get() {
        output.write_all(&buf)?;
    }

    Ok(())
}

fn main() {
    let mut input = stdin();
    let mut output = stdout();

    dup_input(&mut input, &mut output, NonZeroUsize::new(2).unwrap())
        .expect("Failed to duplicate input");
}
</code>```

With this version, the test can be written like this:

```<code>#[cfg(test)]
mod tests {
    use super::*;
    use std::io::Cursor;

    #[test]
    fn test() {
        let mut input = Cursor::new([b't', b'e', b's', b't', b'\n']);
        let mut output = Vec::<u8>::new();

        assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());

        assert_eq!(output.len(), 15);
    }
}
</code>```

We don't need to use Any at all here: output is simply a Vec<u8>.

Title: Unboxing and inspecting a trait object

Body:
Here's a simple application that duplicates 2 times on stdout the contents of stdin:

use std::{
    io,
    io::{stdin, stdout, Read, Write},
    num::NonZeroUsize,
};

fn dup_input(
    input: &mut Box<dyn Read>,
    output: &mut Box<dyn Write>,
    count: NonZeroUsize,
) -> io::Result<()> {
    let mut buf = Vec::new();

    input.read_to_end(&mut buf)?;

    for _idx in 0..count.get() {
        output.write_all(&buf)?;
    }

    Ok(())
}

fn main() {
    let mut input: Box<dyn Read> = Box::new(stdin());
    let mut output: Box<dyn Write> = Box::new(stdout());

    dup_input(&mut input, &mut output, NonZeroUsize::new(2).unwrap())
        .expect("Failed to duplicate input");
}

This part works fine. I want to put a unit test on top of this and this is where the problem lies. The closest I've got to build is with the following attempt:

#[cfg(test)]
mod tests {
    use super::*;
    use std::{any::Any, io::Cursor};

    #[test]
    fn test() {
        let mut input: Box<dyn Read> = Box::new(Cursor::new([b't', b'e', b's', b't', b'\n']));
        let mut output: Box<dyn Write + Any> = Box::new(Vec::<u8>::new());

        assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());

        assert_eq!(output.downcast::<Vec<u8>>().unwrap().len(), 15);
    }
}

but rust 1.41.0 doesn't agree:

$ cargo test
   Compiling unbox-example v0.1.0 (/XXX/unbox-example)
error[E0225]: only auto traits can be used as additional traits in a trait object
  --> src/main.rs:39:41
   |
39 |         let mut output: Box<dyn Write + Any> = Box::new(Vec::<u8>::new());
   |                                 -----   ^^^
   |                                 |       |
   |                                 |       additional non-auto trait
   |                                 |       trait alias used in trait object type (additional use)
   |                                 first non-auto trait
   |                                 trait alias used in trait object type (first use)

error[E0308]: mismatched types
  --> src/main.rs:41:39
   |
41 |         assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());
   |                                       ^^^^^^^^^^^ expected trait `std::io::Write`, found a different trait `std::io::Write`
   |
   = note: expected mutable reference `&mut std::boxed::Box<(dyn std::io::Write + 'static)>`
              found mutable reference `&mut std::boxed::Box<(dyn std::io::Write + 'static)>`

error[E0599]: no method named `downcast` found for type `std::boxed::Box<(dyn std::io::Write + 'static)>` in the current scope
  --> src/main.rs:43:27
   |
43 |         assert_eq!(output.downcast::<Vec<u8>>().unwrap().len(), 15);
   |                           ^^^^^^^^ method not found in `std::boxed::Box<(dyn std::io::Write + 'static)>`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0225, E0308, E0599.
For more information about an error, try `rustc --explain E0225`.
error: could not compile `unbox-example`.

To learn more, run the command again with --verbose.

Is there a way to change the unit test without changing the main code? Note: I could have used generics while implementing dup_input and make the problem significantly easier to solve but this code is part of a broader application and I have to use Read/Write trait objects.

Body:
Passing a mutable reference to a Box to dup_input is unnecessarily complicated. You can simply pass a mutable reference to the trait object.

use std::{
    io,
    io::{stdin, stdout, Read, Write},
    num::NonZeroUsize,
};

fn dup_input(
    input: &mut dyn Read,
    output: &mut dyn Write,
    count: NonZeroUsize,
) -> io::Result<()> {
    let mut buf = Vec::new();

    input.read_to_end(&mut buf)?;

    for _idx in 0..count.get() {
        output.write_all(&buf)?;
    }

    Ok(())
}

fn main() {
    let mut input = stdin();
    let mut output = stdout();

    dup_input(&mut input, &mut output, NonZeroUsize::new(2).unwrap())
        .expect("Failed to duplicate input");
}

With this version, the test can be written like this:

#[cfg(test)]
mod tests {
    use super::*;
    use std::io::Cursor;

    #[test]
    fn test() {
        let mut input = Cursor::new([b't', b'e', b's', b't', b'\n']);
        let mut output = Vec::<u8>::new();

        assert!(dup_input(&mut input, &mut output, NonZeroUsize::new(3).unwrap()).is_ok());

        assert_eq!(output.len(), 15);
    }
}

We don't need to use Any at all here: output is simply a Vec<u8>.