问:
Interface with default key value types that can be extended TypeScript
In many of my projects, I have a common pattern which repeats over and over again.

```<code>type RequestStatus =
  | 'pending'
  | 'requesting'
  | 'successful'
  | 'failed'

type AValue = string | undefined

type OtherValue = number

interface State {
  requestStatus: RequestStatus;
  aValue?: AValue;
  otherValue?: OtherValue;
}

const [requestState, setRequestState] = useState<State>({
  requestStatus: 'pending',
  aValue: 'aValue',
  otherValue: 11
});

const appendToState = (state: Partial<State>) =>
  setRequestState(previousState => ({ ...previousState, ...state }));
</code>```

In such a scenario, I am fetching values and changing the UI based on the requestStatus and the values.

This repeats over and over again in my projects and in an attempt to reduce the repetitions, I am considering wrapping all this in a hook. My main problem is dealing with types.

This was one of my attempts.

```<code>export const useExtendedRequestStatus = <T>(state: T) => {
  const [requestState, setRequestState] = useState<{ requestStatus: RequestStatus } & T>({
    requestStatus: 'pending',
    ...state,
  });

  const appendToState = (state: Partial<T>) =>
    setRequestState(previousState => ({ ...previousState, ...state }));

  return { requestState, setRequestState, appendToState };
};
</code>```

And i would implement it like this

```<code>const {
  requestStatus,
  appendToState
} = useExtendedRequestStatus<{ requestStatus: RequestStatus; aValue: AValue }>({
  aValue: aValue,
  requestStatus: 'successful',
});
</code>```

It works but not perfectly. There are instances if I am statically type checking the hook, I have to re-define the RequestStatus type which is already defined in the hook. I am wondering if there is a way, RequestStatus will still be in the hook when manually type checking without having to re-define it.

I am open to any ideas.

答:
You indeed use a T generic in your useExtendedRequestStatus custom hook, which describes the possible members of the state you want to use it with.

But since you specify that the state argument, when you call your custom hook, is of type T directly, if you want it to include an initial requestStatus, then you are forced to also mention this requestStatus member in your explicit concrete type (of course you could rely on automatic type inference, but I guess you have your reasons to manually type check).

You can easily "embed" this predefined member in your custom hook, and have it available for your argument (same for appendToState), in a very similar manner you have already done with your inner useState<{ requestStatus: RequestStatus } & T>({...}): simply specify that your state argument is also of type T & { requestStatus: RequestStatus } (or maybe even better T & Partial<{ requestStatus: RequestStatus }> in case requestStatus can be initially omitted, as suggested by your initial default value in your custom hook). That way, T no longer needs to contain the requestStatus member. Same for appendToState.

```<code>interface IRequestStatus {
  requestStatus: RequestStatus;
}

export const useExtendedRequestStatus = <T>(
  state: T & Partial<IRequestStatus> // Initial state can contain requestStatus, even if not mentioned in concrete T
) => {
  const [requestState, setRequestState] = useState<IRequestStatus & T>({
    requestStatus: 'pending',
    ...state,
  });

  const appendToState = (state: Partial<T & IRequestStatus>) =>
    setRequestState((previousState) => ({ ...previousState, ...state }));

  return { requestState, setRequestState, appendToState };
};
</code>```

Now in your React functional component, you can use it like this:

```<code>const { requestState, appendToState } = useExtendedRequestStatus<{
  //requestStatus: RequestStatus; // Can now be omitted
  aValue: AValue;
}>({
  aValue: aValue,
  requestStatus: 'successful', // Okay
});

requestState.requestStatus; // Okay

appendToState({
  requestStatus: 'successful', // Okay
});
</code>```

Demo: https://stackblitz.com/edit/react-ts-eyyzhg?file=Hello.tsx

Body:
In many of my projects, I have a common pattern which repeats over and over again.

type RequestStatus =
  | 'pending'
  | 'requesting'
  | 'successful'
  | 'failed'

type AValue = string | undefined

type OtherValue = number

interface State {
  requestStatus: RequestStatus;
  aValue?: AValue;
  otherValue?: OtherValue;
}

const [requestState, setRequestState] = useState<State>({
  requestStatus: 'pending',
  aValue: 'aValue',
  otherValue: 11
});

const appendToState = (state: Partial<State>) =>
  setRequestState(previousState => ({ ...previousState, ...state }));

In such a scenario, I am fetching values and changing the UI based on the requestStatus and the values.

This repeats over and over again in my projects and in an attempt to reduce the repetitions, I am considering wrapping all this in a hook. My main problem is dealing with types.

This was one of my attempts.

export const useExtendedRequestStatus = <T>(state: T) => {
  const [requestState, setRequestState] = useState<{ requestStatus: RequestStatus } & T>({
    requestStatus: 'pending',
    ...state,
  });

  const appendToState = (state: Partial<T>) =>
    setRequestState(previousState => ({ ...previousState, ...state }));

  return { requestState, setRequestState, appendToState };
};

And i would implement it like this

const {
  requestStatus,
  appendToState
} = useExtendedRequestStatus<{ requestStatus: RequestStatus; aValue: AValue }>({
  aValue: aValue,
  requestStatus: 'successful',
});

It works but not perfectly. There are instances if I am statically type checking the hook, I have to re-define the RequestStatus type which is already defined in the hook. I am wondering if there is a way, RequestStatus will still be in the hook when manually type checking without having to re-define it.

I am open to any ideas.

Body:
You indeed use a T generic in your useExtendedRequestStatus custom hook, which describes the possible members of the state you want to use it with.

But since you specify that the state argument, when you call your custom hook, is of type T directly, if you want it to include an initial requestStatus, then you are forced to also mention this requestStatus member in your explicit concrete type (of course you could rely on automatic type inference, but I guess you have your reasons to manually type check).

You can easily "embed" this predefined member in your custom hook, and have it available for your argument (same for appendToState), in a very similar manner you have already done with your inner useState<{ requestStatus: RequestStatus } & T>({...}): simply specify that your state argument is also of type T & { requestStatus: RequestStatus } (or maybe even better T & Partial<{ requestStatus: RequestStatus }> in case requestStatus can be initially omitted, as suggested by your initial default value in your custom hook). That way, T no longer needs to contain the requestStatus member. Same for appendToState.

interface IRequestStatus {
  requestStatus: RequestStatus;
}

export const useExtendedRequestStatus = <T>(
  state: T & Partial<IRequestStatus> // Initial state can contain requestStatus, even if not mentioned in concrete T
) => {
  const [requestState, setRequestState] = useState<IRequestStatus & T>({
    requestStatus: 'pending',
    ...state,
  });

  const appendToState = (state: Partial<T & IRequestStatus>) =>
    setRequestState((previousState) => ({ ...previousState, ...state }));

  return { requestState, setRequestState, appendToState };
};

Now in your React functional component, you can use it like this:

const { requestState, appendToState } = useExtendedRequestStatus<{
  //requestStatus: RequestStatus; // Can now be omitted
  aValue: AValue;
}>({
  aValue: aValue,
  requestStatus: 'successful', // Okay
});

requestState.requestStatus; // Okay

appendToState({
  requestStatus: 'successful', // Okay
});

Demo: https://stackblitz.com/edit/react-ts-eyyzhg?file=Hello.tsx


来源: stackexchange

问:
How to fix : Navigation bar icons still showing, when pop-up menu is opened (Full screen - Immersive sticky)
I'm trying to achieve a full-screen application, where the user doesn't have any access to the status- & navigation-bar.

Preferably I would want them to be removed completely, but from what I've read this is not possible unless you root the device

So my question basically is: How do I hide the navigation-bar icons, when I show the pop-up menu?

BEFORE

AFTER

So far, I have tried:

Calling hideNavigation() before & after the pop-up menu is shown

Calling hideNavigation() in onCreate(), onResume() & onWindowFocusChanged()

Requesting focus to another view

Trying to clear the focus from the drop-down (Failed attempt, didn't really find a way to do this)

Changing the icon colors, "faking" it would be hidden (Failed attempt, didn't really find a way to do this)

Using hideNavigation() in combination with Handler (Failed attempt, maybe I didn't do it correctly)

Trying to configure some COSU/KIOSK-mode options (Perhaps there is some way to complete disable the whole navigation-bar? I haven't found a way to hide the back-button yet)

ACTIVITY

```<code>
    class PinCodeActivity, HasTitleBar {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_pin_code)
            initTitleBarWith(this)
            hideNavigation()
        }

        override fun onResume() {
            super.onResume()
            hideNavigation()
        }

        fun hideNavigation() {
            window.decorView.apply {
                systemUiVisibility = FLAGS
            }
        }

        override fun onWindowFocusChanged(hasFocus: Boolean) {
            super.onWindowFocusChanged(hasFocus)
            hideNavigation()
        }
    }

const val FLAGS = (View.SYSTEM_UI_FLAG_LOW_PROFILE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)

</code>```

TITLE-BAR

```<code>
    fun HasTitleBar.initTitleBarWith(activity: Activity, resId: Int = R.id.titleBar) {
        val langButton = activity.findViewById<View>(resId).findViewById<Button>(R.id.tbLanguageChoiceBtn)
        val wrapper = ContextThemeWrapper(activity, R.style.MyPopupMenu)
        val popupMenu = PopUpLanguageMenu(wrapper, langButton)
        langButton.setOnClickListener {
            activity.hideNavigation()
            popupMenu.showMenu()
            activity.hideNavigation()
        }
    }

</code>```

POP-UP MENU

```<code>
    class PopUpLanguageMenu constructor(context: Context, view: View) : PopupMenu(context, view) {

        private var popupHelper: MenuPopupHelper

        init {
            val popUpMenu = PopupMenu(context, view).apply {
                inflate(R.menu.menu_language_dropdown)
            }

            popupHelper = MenuPopupHelper(context, popUpMenu.menu as MenuBuilder, view)
            popupHelper.run {
                gravity = Gravity.END
                setForceShowIcon(true)
            }
        }

        fun showMenu() {
            popupHelper.show()
        }
    }

</code>```

EXPECTED RESULT: Navigation-bar & it's icons are hidden, after the pop-up menu is shown, the icons are still HIDDEN

ACTUAL RESULT: Navigation-bar & it's icons are hidden, after the pop-up menu is shown, the icons are SHOWN

答:
Because PopupMenu use new DecorView (PopupDecorView), try:</p>
```<code>@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if(hasFocus)
    {
        fullSceen(getWindow().getDecorView());
    }
    else {
        try {
            Object wmgInstance = Class.forName("android.view.WindowManagerGlobal").getMethod("getInstance").invoke(null);
            Field viewsField = Class.forName("android.view.WindowManagerGlobal").getDeclaredField("mViews");

            viewsField.setAccessible(true);
            ArrayList<View> views = (ArrayList<View>) viewsField.get(wmgInstance);
            for (View view: views) {
                fullSceen(view);

                view.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                    @Override
                    public void onSystemUiVisibilityChange(int visibility) {
                        fullSceen(view);
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        AppUtils.console(this,TAG, "hasFocus == false");
    }
}
private void fullSceen(View view){
    view.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to achieve a full-screen application, where the user doesn't have any access to the status- & navigation-bar.

Preferably I would want them to be removed completely, but from what I've read this is not possible unless you root the device

So my question basically is: How do I hide the navigation-bar icons, when I show the pop-up menu?

BEFORE

AFTER

So far, I have tried:

Calling hideNavigation() before & after the pop-up menu is shown

Calling hideNavigation() in onCreate(), onResume() & onWindowFocusChanged()

Requesting focus to another view

Trying to clear the focus from the drop-down (Failed attempt, didn't really find a way to do this)

Changing the icon colors, "faking" it would be hidden (Failed attempt, didn't really find a way to do this)

Using hideNavigation() in combination with Handler (Failed attempt, maybe I didn't do it correctly)

Trying to configure some COSU/KIOSK-mode options (Perhaps there is some way to complete disable the whole navigation-bar? I haven't found a way to hide the back-button yet)

ACTIVITY

    class PinCodeActivity, HasTitleBar {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_pin_code)
            initTitleBarWith(this)
            hideNavigation()
        }

        override fun onResume() {
            super.onResume()
            hideNavigation()
        }

        fun hideNavigation() {
            window.decorView.apply {
                systemUiVisibility = FLAGS
            }
        }

        override fun onWindowFocusChanged(hasFocus: Boolean) {
            super.onWindowFocusChanged(hasFocus)
            hideNavigation()
        }
    }

const val FLAGS = (View.SYSTEM_UI_FLAG_LOW_PROFILE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)

TITLE-BAR

    fun HasTitleBar.initTitleBarWith(activity: Activity, resId: Int = R.id.titleBar) {
        val langButton = activity.findViewById<View>(resId).findViewById<Button>(R.id.tbLanguageChoiceBtn)
        val wrapper = ContextThemeWrapper(activity, R.style.MyPopupMenu)
        val popupMenu = PopUpLanguageMenu(wrapper, langButton)
        langButton.setOnClickListener {
            activity.hideNavigation()
            popupMenu.showMenu()
            activity.hideNavigation()
        }
    }

POP-UP MENU

    class PopUpLanguageMenu constructor(context: Context, view: View) : PopupMenu(context, view) {

        private var popupHelper: MenuPopupHelper

        init {
            val popUpMenu = PopupMenu(context, view).apply {
                inflate(R.menu.menu_language_dropdown)
            }

            popupHelper = MenuPopupHelper(context, popUpMenu.menu as MenuBuilder, view)
            popupHelper.run {
                gravity = Gravity.END
                setForceShowIcon(true)
            }
        }

        fun showMenu() {
            popupHelper.show()
        }
    }

EXPECTED RESULT: Navigation-bar & it's icons are hidden, after the pop-up menu is shown, the icons are still HIDDEN

ACTUAL RESULT: Navigation-bar & it's icons are hidden, after the pop-up menu is shown, the icons are SHOWN

Body:
Because PopupMenu use new DecorView (PopupDecorView), try:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if(hasFocus)
    {
        fullSceen(getWindow().getDecorView());
    }
    else {
        try {
            Object wmgInstance = Class.forName("android.view.WindowManagerGlobal").getMethod("getInstance").invoke(null);
            Field viewsField = Class.forName("android.view.WindowManagerGlobal").getDeclaredField("mViews");

            viewsField.setAccessible(true);
            ArrayList<View> views = (ArrayList<View>) viewsField.get(wmgInstance);
            for (View view: views) {
                fullSceen(view);

                view.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                    @Override
                    public void onSystemUiVisibilityChange(int visibility) {
                        fullSceen(view);
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        AppUtils.console(this,TAG, "hasFocus == false");
    }
}
private void fullSceen(View view){
    view.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}


问:
The argument type 'Object?' can't be assigned to the parameter type 'String?
I get this error with my function, "The argument type 'Object?' can't be assigned to the parameter type 'String?'." on the lines containing snapshot.docs[0].data(''),

Please help me fix it, any help would be greatly appreciated!

```<code>Future getNewsPostDetails(String newsPostId) async {

    QuerySnapshot snapshot = await FirebaseFirestore.instance.collection('newsPosts').where('newsPostId', isEqualTo: newsPostId).get();
      newsPostDetails blogPostDetails = newsPostDetails(
      newsPostTitle: snapshot.docs[0].data('newsPostTitle'),
      newsPostAuthor: snapshot.docs[0].data('newsPostAuthor'),
      newsPostContent: snapshot.docs[0].data('newsPostContent') ,
      date: snapshot.docs[0].data('date'),
    );
    return blogPostDetails;
  }
</code>```

答:
If you make sure that snapshot.docs[0].data('newsPostTitle') is a String, you can convert it to String like:

```<code>snapshot.docs[0].data('newsPostTitle') as String?
</code>```

Body:
I get this error with my function, "The argument type 'Object?' can't be assigned to the parameter type 'String?'." on the lines containing snapshot.docs[0].data(''),

Please help me fix it, any help would be greatly appreciated!

Future getNewsPostDetails(String newsPostId) async {

    QuerySnapshot snapshot = await FirebaseFirestore.instance.collection('newsPosts').where('newsPostId', isEqualTo: newsPostId).get();
      newsPostDetails blogPostDetails = newsPostDetails(
      newsPostTitle: snapshot.docs[0].data('newsPostTitle'),
      newsPostAuthor: snapshot.docs[0].data('newsPostAuthor'),
      newsPostContent: snapshot.docs[0].data('newsPostContent') ,
      date: snapshot.docs[0].data('date'),
    );
    return blogPostDetails;
  }

Body:
If you make sure that snapshot.docs[0].data('newsPostTitle') is a String, you can convert it to String like:

snapshot.docs[0].data('newsPostTitle') as String?


问:
Google Maps API v3: Does placemarker exist on given LatLng?
I want to find out using the API if a marker has been placed on google maps at a given LatLng. Is this possible without me saving all the latlngs at which the placemarker is placed?

答:
No. The API doesn't track your markers, so you will need to track them yourself. I suggest adding each location to an array, and then writing a function which can check whether any marker in that array is located at a specific lat/lng.

Something like:

```<code>var marker_locations = [];

function addMarker(latlng) {
   marker = new google.maps.Marker(....);
   marker.setMap(map);
   marker_locations.push(latlng);
}

function markerAtPoint(latlng) {
  for (var i = 0; i < marker_locations.length; ++i) {
    if (marker_locations[i].equals(latlng)) return true;
  }
  return false;
}
</code>```

ContentLicense: CC BY-SA 3.0

Body:
No. The API doesn't track your markers, so you will need to track them yourself. I suggest adding each location to an array, and then writing a function which can check whether any marker in that array is located at a specific lat/lng.

Something like:

var marker_locations = [];

function addMarker(latlng) {
   marker = new google.maps.Marker(....);
   marker.setMap(map);
   marker_locations.push(latlng);
}

function markerAtPoint(latlng) {
  for (var i = 0; i < marker_locations.length; ++i) {
    if (marker_locations[i].equals(latlng)) return true;
  }
  return false;
}


问:
Convert columns of R dataframe to JSON
I have this dataframe:

```<code>df <- data.frame(
  option_label_1 = c("thickness", "strength", "color"),
  option_value_1 = c("0.5 in", "2 lb" , "red"),
  option_label_2 = c("size", "color", "thickness"),
  option_value_2 = c("0.5 Inches x 7200 Feet", "blue" , "1 in"),
  option_label_3 = c("stretch", NA, NA),
  option_value_3 = c("wide", NA , NA)
  )
</code>```
```<code>  option_label_1 option_value_1 option_label_2         option_value_2 option_label_3 option_value_3
1      thickness         0.5 in           size 0.5 Inches x 7200 Feet        stretch           wide
2       strength           2 lb          color                   blue           <NA>           <NA>
3          color            red      thickness                   1 in           <NA>           <NA>
</code>```

I want this data frame:

```<code>  option_label_1 option_value_1 option_label_2         option_value_2 option_label_3 option_value_3
1      thickness         0.5 in           size 0.5 Inches x 7200 Feet        stretch           wide
2       strength           2 lb          color                   blue           <NA>           <NA>
3          color            red      thickness                   1 in           <NA>           <NA>
                                                                       json
1 {"thickness":"0.5 in","size":"0.5 Inches x 7200 Feet","stretch":"wide"}
2                                       {"strength":"2 lb","color":"blue"}
3                                        {"color":"red","thickness":"1 in"}
</code>```

Essentially I want a JSON column added to the original df built off of the original columns using the option labels and option values. Please note I do not want a solution that converts the whole dataframe to JSON using toJSON. I have a much larger dataframe with other fields I do not want in JSON. I just want the option_labels and their respective option_values to be in JSON.

I have tried using list and paste functions nested in toJSON, but the "option_labels" are static and don't change accordingly in the resulting JSON column.

Thanks for your help!

答:
You could also do:</p>
```<code>df %>%
  rownames_to_column('rn') %>%
  pivot_longer(-rn, '.value', names_pattern = '(.*)_', values_drop_na = TRUE) %>%
  group_by(rn) %>%
  summarise(json = jsonlite::toJSON(data.table::transpose(cur_data(),make.names = TRUE)))

# A tibble: 3 x 2
  rn    json
  <chr> <json>
1 1     [{"thickness":"0.5 in","size":"0.5 Inches x 7200 Feet","stretch":"wide"}]
2 2     [{"strength":"2 lb","color":"blue"}]
3 3     [{"color":"red","thickness":"1 in"}]
</code>```

Title: Convert columns of R dataframe to JSON

Body:
I have this dataframe:

df <- data.frame(
  option_label_1 = c("thickness", "strength", "color"),
  option_value_1 = c("0.5 in", "2 lb" , "red"),
  option_label_2 = c("size", "color", "thickness"),
  option_value_2 = c("0.5 Inches x 7200 Feet", "blue" , "1 in"),
  option_label_3 = c("stretch", NA, NA),
  option_value_3 = c("wide", NA , NA)
  )

  option_label_1 option_value_1 option_label_2         option_value_2 option_label_3 option_value_3
1      thickness         0.5 in           size 0.5 Inches x 7200 Feet        stretch           wide
2       strength           2 lb          color                   blue           <NA>           <NA>
3          color            red      thickness                   1 in           <NA>           <NA>

I want this data frame:

  option_label_1 option_value_1 option_label_2         option_value_2 option_label_3 option_value_3
1      thickness         0.5 in           size 0.5 Inches x 7200 Feet        stretch           wide
2       strength           2 lb          color                   blue           <NA>           <NA>
3          color            red      thickness                   1 in           <NA>           <NA>
                                                                       json
1 {"thickness":"0.5 in","size":"0.5 Inches x 7200 Feet","stretch":"wide"}
2                                       {"strength":"2 lb","color":"blue"}
3                                        {"color":"red","thickness":"1 in"}

Essentially I want a JSON column added to the original df built off of the original columns using the option labels and option values. Please note I do not want a solution that converts the whole dataframe to JSON using toJSON. I have a much larger dataframe with other fields I do not want in JSON. I just want the option_labels and their respective option_values to be in JSON.

I have tried using list and paste functions nested in toJSON, but the "option_labels" are static and don't change accordingly in the resulting JSON column.

Thanks for your help!

Body:
You could also do:

df %>%
  rownames_to_column('rn') %>%
  pivot_longer(-rn, '.value', names_pattern = '(.*)_', values_drop_na = TRUE) %>%
  group_by(rn) %>%
  summarise(json = jsonlite::toJSON(data.table::transpose(cur_data(),make.names = TRUE)))

# A tibble: 3 x 2
  rn    json
  <chr> <json>
1 1     [{"thickness":"0.5 in","size":"0.5 Inches x 7200 Feet","stretch":"wide"}]
2 2     [{"strength":"2 lb","color":"blue"}]
3 3     [{"color":"red","thickness":"1 in"}]


问:
Replacing a number in an array if duplicates are found
Make the user enter 5 integer values into the array in the main method. Pass array into a separate function. There, check for duplicated values in the array. If duplicates are found, eliminate the duplicate integer and replace it with -1.
Print the processed array back in the main method.. i think i know how to replace the value with -1 but how do I return the array to the main back again. The code is:</p>

```<code> package methods;
import java.util.*;
public class remdup {
    public static void main (String[]args) {
    Scanner in = new Scanner (System.in);
    System.out.println("Enter 5 integers:  ");
    int [] x= new int [5];
    for (int i=0; i<5; i++) {
    x[i]=in.nextInt();
}
    check(x);
   // Insert method here
}
    //Method check starts here...
    public static void check(int []y) {
      //  int pos = y[0];
        int len=y.length;
        int i=0;
        int j = i+1;
       for (i=0; i<len-1; i++) {
           for (j=i+1; j<len-1;j++ ) {
            if (y[i]==y[j]) {
                //how to replace numbers???
               y[i]=-1;
                System.out.println("Duplicate found");
            }
            }
        }

    }
}
</code>```

答:
Though this is a very old post I think there is an error in the accepted answer. We should be adding the replaced number back to the array. However in the accepted answer we are replacing it with -1 but we are never adding it back to SET.
Below is my corrected solution :</p>
```<code>    public static Set<Integer> check(int []y) {
        Set<Integer> foundNumbers = new HashSet<Integer>();

        for(int index = 0; index < y.length; index++) {
            if(foundNumbers.contains(y[index])){
                y[index] = -1;

            }

            foundNumbers.add(y[index]);
        }
         return foundNumbers;

    }
</code>```

Body:
Make the user enter 5 integer values into the array in the main method. Pass array into a separate function. There, check for duplicated values in the array. If duplicates are found, eliminate the duplicate integer and replace it with -1.
Print the processed array back in the main method.. i think i know how to replace the value with -1 but how do I return the array to the main back again. The code is:

 package methods;
import java.util.*;
public class remdup {
    public static void main (String[]args) {
    Scanner in = new Scanner (System.in);
    System.out.println("Enter 5 integers:  ");
    int [] x= new int [5];
    for (int i=0; i<5; i++) {
    x[i]=in.nextInt();
}
    check(x);
   // Insert method here
}
    //Method check starts here...
    public static void check(int []y) {
      //  int pos = y[0];
        int len=y.length;
        int i=0;
        int j = i+1;
       for (i=0; i<len-1; i++) {
           for (j=i+1; j<len-1;j++ ) {
            if (y[i]==y[j]) {
                //how to replace numbers???
               y[i]=-1;
                System.out.println("Duplicate found");
            }
            }
        }

    }
}

Body:
Though this is a very old post I think there is an error in the accepted answer. We should be adding the replaced number back to the array. However in the accepted answer we are replacing it with -1 but we are never adding it back to SET.
Below is my corrected solution :

    public static Set<Integer> check(int []y) {
        Set<Integer> foundNumbers = new HashSet<Integer>();

        for(int index = 0; index < y.length; index++) {
            if(foundNumbers.contains(y[index])){
                y[index] = -1;

            }

            foundNumbers.add(y[index]);
        }
         return foundNumbers;

    }


问:
Countdown of each dom selector with respect timezone Moment js
I am trying to achieve countdown between now and endtime for multiple table rows with same class selector. I have read all other related posts, but my jsfiddle gives script error.

My html page:

```<code><table>
  <tr>
    <td>Blocked-1</td>
    <td class="bidtime-countdown" data-bidtime="2022-02-09 01:00:00" data-endtime="2022-02-11 04:00:00"></td>
  </tr>
  <tr>
    <td>Sold-1</td>
    <td>2022-02-09 00:20:00</td>
  </tr>
  <tr>
    <td>Blocked-2</td>
    <td class="bidtime-countdown" data-bidtime="2022-02-09 01:30:00" data-endtime="2022-02-11 05:30:00"></td>
  </tr>
</table>
</code>```

The endtime provided in html is Asia/Dubai local timezone. So I need countdown in relation with this local timezone.

I could not found solution for this. Any guide ? Below is my jsfiddle that i was working on.

JSFIDDLE

答:
It seems you are using diff wrong and also it works on objects only. Try toDate with jquery countdown instead.

Try this:

```<code>$(function() {
  $('[data-endtime]').each(function() {
    var $this = $(this);
    var end = $(this).data('endtime');
    $this.countdown(moment.tz(end, "Asia/Dubai").toDate(), function(event) {
      $this.html(event.strftime('%d day %H:%M:%S'));
    });
  });
});
</code>```

demo

Add: moment.min.js, moment-timezone-with-data.js, and jquery-countdown.min.js libraries as in demo.

Body:
I am trying to achieve countdown between now and endtime for multiple table rows with same class selector. I have read all other related posts, but my jsfiddle gives script error.

My html page:

    Blocked-1

    Sold-1
    2022-02-09 00:20:00

    Blocked-2

The endtime provided in html is Asia/Dubai local timezone. So I need countdown in relation with this local timezone.

I could not found solution for this. Any guide ? Below is my jsfiddle that i was working on.

JSFIDDLE

Body:
It seems you are using diff wrong and also it works on objects only. Try toDate with jquery countdown instead.

Try this:

$(function() {
  $('[data-endtime]').each(function() {
    var $this = $(this);
    var end = $(this).data('endtime');
    $this.countdown(moment.tz(end, "Asia/Dubai").toDate(), function(event) {
      $this.html(event.strftime('%d day %H:%M:%S'));
    });
  });
});

demo

Add: moment.min.js, moment-timezone-with-data.js, and jquery-countdown.min.js libraries as in demo.


问:
Formatting a line graph in R
My code is a little different from the codes that people usually use when addressing this problem. I am trying to make some formatting adjustments to my code, including adding points to my line graph, and changing the color of the lines and error bars. Thanks in advance!

Reproducible sample:

```<code>set.seed(42)
n <- 100

    dat <- data.frame(Participant=1:n,
                      Environment=rep(LETTERS[1:2], n/2),
                      Condition=rep(LETTERS[25:26], n/2),
                      Gate= sample(1:5, n, replace=TRUE),
                      Block = sample(1:2, n, replace=TRUE),
                      Sound=rep(LETTERS[3:4], n/2),
                      Correct=sample(0:1, n, replace=TRUE)
    )
</code>```

Code:

```<code>dat %>%
  group_by(Condition, Gate = fct_inorder(Gate), Sound) %>% #these relevant columns
  summarize(Accuracy = mean(Correct), #Defining y axis title
            sd = sd(Correct)/sqrt(length(Correct))) %>%     #and SD
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal()
</code>```

答:
Sounds straightforward; does this solve your problem?

library(tidyverse)

set.seed(42)
n <- 100

dat <- data.frame(Participant = 1:n,
                  Environment = rep(LETTERS[1:2], n/2),
                  Condition = rep(LETTERS[25:26], n/2),
                  Gate = sample(1:5, n, replace = TRUE),
                  Block = sample(1:2, n, replace = TRUE),
                  Sound = rep(LETTERS[3:4], n/2),
                  Correct = sample(0:1, n, replace = TRUE)
)

dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal()
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.
```
<p><img src="https://i.imgur.com/hyoK5ny.png" alt="" /></p>
<pre class="lang-r prettyprint-override"><code># Change colour of lines
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.
</code>```

# Add points
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd)) +
  geom_point() +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.
```
<p><img src="https://i.imgur.com/Unneyp1.png" alt="" /></p>
<pre class="lang-r prettyprint-override"><code># different coloured lines, larger points
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd), color = "grey75") +
  geom_point(size = 3) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.
</code>```

Created on 2022-02-09 by the reprex package (v2.0.1)

I highly recommend the books ggplot2: Elegant Graphics for Data Analysis and the R Graphics Cookbook for further information/examples (both free to read online)

Title: Formatting a line graph in R

Body:
My code is a little different from the codes that people usually use when addressing this problem. I am trying to make some formatting adjustments to my code, including adding points to my line graph, and changing the color of the lines and error bars. Thanks in advance!

Reproducible sample:

set.seed(42)
n <- 100

    dat <- data.frame(Participant=1:n,
                      Environment=rep(LETTERS[1:2], n/2),
                      Condition=rep(LETTERS[25:26], n/2),
                      Gate= sample(1:5, n, replace=TRUE),
                      Block = sample(1:2, n, replace=TRUE),
                      Sound=rep(LETTERS[3:4], n/2),
                      Correct=sample(0:1, n, replace=TRUE)
    )

Code:

dat %>%
  group_by(Condition, Gate = fct_inorder(Gate), Sound) %>% #these relevant columns
  summarize(Accuracy = mean(Correct), #Defining y axis title
            sd = sd(Correct)/sqrt(length(Correct))) %>%     #and SD
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal()

Body:
Sounds straightforward; does this solve your problem?

library(tidyverse)

set.seed(42)
n <- 100

dat <- data.frame(Participant = 1:n,
                  Environment = rep(LETTERS[1:2], n/2),
                  Condition = rep(LETTERS[25:26], n/2),
                  Gate = sample(1:5, n, replace = TRUE),
                  Block = sample(1:2, n, replace = TRUE),
                  Sound = rep(LETTERS[3:4], n/2),
                  Correct = sample(0:1, n, replace = TRUE)
)

dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal()
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.

# Change colour of lines
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd,)) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.

# Add points
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd)) +
  geom_point() +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.

# different coloured lines, larger points
dat %>%
  mutate(Gate = factor(Gate),
         Sound = factor(Sound)) %>%
  group_by(Condition, Gate, Sound) %>%
  summarize(Accuracy = mean(Correct),
            sd = sd(Correct)/sqrt(length(Correct))) %>%
  ggplot(aes(x = Gate, y = Accuracy, color = Sound, group = Sound)) +
  geom_line() +
  geom_errorbar(aes(ymin = Accuracy - sd, ymax = Accuracy + sd), color = "grey75") +
  geom_point(size = 3) +
  scale_y_continuous(labels = scales::percent)+
  facet_wrap(~Condition) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1")
#> `summarise()` has grouped output by 'Condition', 'Gate'. You can override using the `.groups` argument.

Created on 2022-02-09 by the reprex package (v2.0.1)

I highly recommend the books ggplot2: Elegant Graphics for Data Analysis and the R Graphics Cookbook for further information/examples (both free to read online)


问:
Retrieving Authenticated User with relation data laravel 8
I'm currently studying about JWT auth on laravel 8. To explain what im trying to do straightforwardly, im trying to send the user data with the relations data when successfully authenticated.
please take a look on my code bellow

```<code>    //response login "success" with generate "Token"
    return response()->json([
        'success' => true,
        'user'    => auth()->guard('api')->user(),
        'token'   => $token
    ], 200);enter code here
</code>```

in this case the api return auth condition with user data and jwt token. but 'user'    => auth()->guard('api')->user() not returning the user data with the relation data. currently my users table has a relation with roles table so i also want to send the role data based on role id in users data. something like eager loading using with() function.
if you have any clue or solution about this please help me to resolve this problems.
Thankyou

答:
You could utilize the lazy loading methods for Laravel Models

https://laravel.com/docs/8.x/eloquent-relationships#lazy-eager-loading

```<code>$user = auth()->guard('api')->user();

$user->load(['relation1', 'relation2']);

return response()->json([
        'success' => true,
        'user'    => $user,
        'token'   => $token
    ], 200);
</code>```

Or you could potentionally ALWAYS load the relationships for the User model by adding them to the Model

https://laravel.com/docs/8.x/eloquent-relationships#eager-loading-by-default

```<code>class User extends ExtendedClasses
{
    /**
     * The relationships that should always be loaded.
     *
     * @var array
     */
    protected $with = ['relation1', 'relation2'];
</code>```

Body:
I'm currently studying about JWT auth on laravel 8. To explain what im trying to do straightforwardly, im trying to send the user data with the relations data when successfully authenticated.
please take a look on my code bellow

    //response login "success" with generate "Token"
    return response()->json([
        'success' => true,
        'user'    => auth()->guard('api')->user(),
        'token'   => $token
    ], 200);enter code here

in this case the api return auth condition with user data and jwt token. but 'user'    => auth()->guard('api')->user() not returning the user data with the relation data. currently my users table has a relation with roles table so i also want to send the role data based on role id in users data. something like eager loading using with() function.
if you have any clue or solution about this please help me to resolve this problems.
Thankyou

Body:
You could utilize the lazy loading methods for Laravel Models

https://laravel.com/docs/8.x/eloquent-relationships#lazy-eager-loading

$user = auth()->guard('api')->user();

$user->load(['relation1', 'relation2']);

return response()->json([
        'success' => true,
        'user'    => $user,
        'token'   => $token
    ], 200);

Or you could potentionally ALWAYS load the relationships for the User model by adding them to the Model

https://laravel.com/docs/8.x/eloquent-relationships#eager-loading-by-default

class User extends ExtendedClasses
{
    /**
     * The relationships that should always be loaded.
     *
     * @var array
     */
    protected $with = ['relation1', 'relation2'];


问:
Please help me to understand the use of "->" in Arrays.sort()
I was solving problems in GeeksforGeeks and suddenly got this. I understand the use of "Integer.compare", but could not get the use of "->" in the sortBySetBitCount method.</p>
```<code>static void sortBySetBitCount(Integer arr[], int n)
{
    Arrays.sort(arr, (a, b) -> Integer.compare(countSetBit(b), countSetBit(a)));
         //I mean here the "->" operator
}

static int countSetBit(int n) {
    int count = 0;
    while (n>0) {
        n = n & (n - 1);
        count += 1;
    }
    return count;
}
</code>```

答:
Lambda expressions are added in Java 8 and provide below
functionalities.

Enable to treat functionality as a method argument, or code as data.

A function that can be created without belonging to any class.

A lambda expression can be passed around as if it was an object and executed on demand.

Syntax:

```<code>lambda operator -> body
</code>```

where lambda operator can be:

Zero parameter:

```<code>() -> System.out.println("Zero parameter lambda");
</code>```

One parameter:–

```<code>(p) -> System.out.println("One parameter: " + p);
</code>```

It is not mandatory to use parentheses, if the type of that variable can be inferred from the context

Multiple parameters :

(p1, p2) -> System.out.println("Multiple parameters: " + p1 + ", " + p2);

Source for above examples GeeksForGeeks.

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

class MainClass{
    public static void main(String ... $){
        var out = System.out;
        Integer arr[] = {10, 32, 31};
        sortBySetBitCount(arr);
        //output is 31, 10, 32
        //31 has 5 set bits
        //10 has 3 set bits
        //32 has 1 set bit
        out.println(Arrays.asList(arr));

    }
    static void sortBySetBitCount(Integer arr[]){
        //first argument is array they we want to sort
        //second argument is a lambda method
        Arrays.sort(arr, (a, b) -> Integer.compare(countSetBit(b), countSetBit(a)));
    }
    //Returns numbers of bit set
    static int countSetBit(int n) {
        int count = 0;
        while (n != 0) {
            n = n & (n - 1);
            count += 1;
        }
        return count;
    }
}
</code>```

output:

```<code>$ javac MainClass.java && java MainClass
[31, 10, 32]
</code>```

More about lambda methods:

Lambda method in java

Body:
I was solving problems in GeeksforGeeks and suddenly got this. I understand the use of "Integer.compare", but could not get the use of "->" in the sortBySetBitCount method.

static void sortBySetBitCount(Integer arr[], int n)
{
    Arrays.sort(arr, (a, b) -> Integer.compare(countSetBit(b), countSetBit(a)));
         //I mean here the "->" operator
}

static int countSetBit(int n) {
    int count = 0;
    while (n>0) {
        n = n & (n - 1);
        count += 1;
    }
    return count;
}

Body:
Lambda expressions are added in Java 8 and provide below
functionalities.

Enable to treat functionality as a method argument, or code as data.

A function that can be created without belonging to any class.

A lambda expression can be passed around as if it was an object and executed on demand.

Syntax:

lambda operator -> body

where lambda operator can be:

Zero parameter:

() -> System.out.println("Zero parameter lambda");

One parameter:–

(p) -> System.out.println("One parameter: " + p);

It is not mandatory to use parentheses, if the type of that variable can be inferred from the context

Multiple parameters :

(p1, p2) -> System.out.println("Multiple parameters: " + p1 + ", " + p2);

Source for above examples GeeksForGeeks.

import java.util.*;

class MainClass{
    public static void main(String ... $){
        var out = System.out;
        Integer arr[] = {10, 32, 31};
        sortBySetBitCount(arr);
        //output is 31, 10, 32
        //31 has 5 set bits
        //10 has 3 set bits
        //32 has 1 set bit
        out.println(Arrays.asList(arr));

    }
    static void sortBySetBitCount(Integer arr[]){
        //first argument is array they we want to sort
        //second argument is a lambda method
        Arrays.sort(arr, (a, b) -> Integer.compare(countSetBit(b), countSetBit(a)));
    }
    //Returns numbers of bit set
    static int countSetBit(int n) {
        int count = 0;
        while (n != 0) {
            n = n & (n - 1);
            count += 1;
        }
        return count;
    }
}

output:

$ javac MainClass.java && java MainClass
[31, 10, 32]

More about lambda methods:

Lambda method in java


问:
Custom function to rename all columns
I want to manipulate the names of all the columns in a dataframe with this function that I wrote:

```<code>clean_names <- function(df) {
  names(df) <- tolower(names(df))
  names(df) <- gsub('\\s', '\\_', names(df))
  names(df) <- gsub('\\(|\\)|\\/|,|\\.', '\\_', names(df))
  names(df) <- gsub('(\\_)\\_', '\\1', names(df))
  names(df) <- gsub('\\_$', '', names(df))
}
</code>```

That said, when actually called, it doesn't do anything (no error just nothing).
What's the problem here?

I suspect the problem is that I'm only assigning things and not returning anything. But in this case I don't want to return a value just change the column names.

The only parameter here is df and I'm calling the names() function multiple times. Shouldn't this work? Any help is appreciated!

答:
From the names documentation:

For names<-, the updated object. (Note that the value of names(x) <- value is that of the assignment, value, not the return value from the left-hand side.)

Therefore you should try:

```<code>clean_names <- function(df) {
  names(df) <- tolower(names(df))
  names(df) <- gsub('\\s', '\\_', names(df))
  names(df) <- gsub('\\(|\\)|\\/|,|\\.', '\\_', names(df))
  names(df) <- gsub('(\\_)\\_', '\\1', names(df))
  names(df) <- gsub('\\_$', '', names(df))
  return(df)
}
</code>```

Title: Custom function to rename all columns

Body:
I want to manipulate the names of all the columns in a dataframe with this function that I wrote:

clean_names <- function(df) {
  names(df) <- tolower(names(df))
  names(df) <- gsub('\\s', '\\_', names(df))
  names(df) <- gsub('\\(|\\)|\\/|,|\\.', '\\_', names(df))
  names(df) <- gsub('(\\_)\\_', '\\1', names(df))
  names(df) <- gsub('\\_$', '', names(df))
}

That said, when actually called, it doesn't do anything (no error just nothing).
What's the problem here?

I suspect the problem is that I'm only assigning things and not returning anything. But in this case I don't want to return a value just change the column names.

The only parameter here is df and I'm calling the names() function multiple times. Shouldn't this work? Any help is appreciated!

Body:
From the names documentation:

For names<-, the updated object. (Note that the value of names(x) <- value is that of the assignment, value, not the return value from the left-hand side.)

Therefore you should try:

clean_names <- function(df) {
  names(df) <- tolower(names(df))
  names(df) <- gsub('\\s', '\\_', names(df))
  names(df) <- gsub('\\(|\\)|\\/|,|\\.', '\\_', names(df))
  names(df) <- gsub('(\\_)\\_', '\\1', names(df))
  names(df) <- gsub('\\_$', '', names(df))
  return(df)
}


问:
What devices have LDPI resolution with Android 2.2/2.3 version?
What devices have LDPI(Low resolution) with Android 2.2\2.3 version?</p>

答: Here you have the complete list of Android Devices, just search and check resolutions: http://www.google.com/phone/#manufacturer=all&category=all&carrier=all&country=es&reset_filters=1</p>


问:
Check if a child node exists 2 levels deep
I need to check if a json node exists.

```<code>ownerid = jsonData[0]['owner']['id']
</code>```

If this exists I dont have an issue. There are times when owner node is not there so I have this and it works

```<code>if("owner" in jdata): #jdata is of type string
     ownerid = jsonData[0]['owner']['id']
else:
     ownerid = jsonData[0]['owner']['id']
</code>```

This will work when owner does not exists.

My issue is when owner node exists but the 'id' node does not because the owner condition is met and id does not exists so my process fails.

Here is the question how do I check for that specific node inside owner.

I can not use

```<code>if("id" in jdata) #jdata is of type string
</code>```

The search word "id" is very common in file. I will get hits but does not necessarily mean id exists inside owner node. How can I check for id with a specific node so I can determine what to do next

FYI... I tried

```<code>if("id" in jsonData[0]['owner']) #jsonData of type list
</code>```

got an error

```<code>argument of type 'NoneType' is not iterable
</code>```

答:
use dict.get() avoid NoneType error</p>
```<code>ownerid = jsonData[0].get('owner',{}).get('id')
if ownerid:
    print('ownerid exist')
else:
    print('ownerid not exist')
</code>```

Body:
I need to check if a json node exists.

ownerid = jsonData[0]['owner']['id']

If this exists I dont have an issue. There are times when owner node is not there so I have this and it works

if("owner" in jdata): #jdata is of type string
     ownerid = jsonData[0]['owner']['id']
else:
     ownerid = jsonData[0]['owner']['id']

This will work when owner does not exists.

My issue is when owner node exists but the 'id' node does not because the owner condition is met and id does not exists so my process fails.

Here is the question how do I check for that specific node inside owner.

I can not use

if("id" in jdata) #jdata is of type string

The search word "id" is very common in file. I will get hits but does not necessarily mean id exists inside owner node. How can I check for id with a specific node so I can determine what to do next

FYI... I tried

if("id" in jsonData[0]['owner']) #jsonData of type list

got an error

argument of type 'NoneType' is not iterable

Body:
use dict.get() avoid NoneType error

ownerid = jsonData[0].get('owner',{}).get('id')
if ownerid:
    print('ownerid exist')
else:
    print('ownerid not exist')


问:
Plotly Dash in Kubernetes pod cannot get assets for IFrame
The idea is to display .html file in html.iFrame in Plotly Dash hosted in Kubernetes.

The code works as intended in local however it's met with 404 ( in K8s log ) when trying to fetch the file in the pod (/project/assets/). I have went into the pod to check and the files are there. I have checked for file permissions and they are the same as local (-rw-r--r--), parents folders have the same permissions too. I have some other files in /project/cache folders that can be successfully displayed through dcc.Graph indicating that io is fine.

```<code>100.64.109.71 - - [04/Feb/2022 02:41:58] "POST /_dash-update-component HTTP/1.1" 200 -
100.64.109.71 - - [04/Feb/2022 02:41:58] "GET /assets/country/datetime/filename.html HTTP/1.1" 404 -
</code>```

Is there something unique about html.iFrame in Kubernetes that I have missed out? My apologies if the question is too terse but I am not even sure where or how to start debugging.

Update 1: Found useful reference ( https://github.com/plotly/dash/issues/489 )

答:
Solved using srcDoc instead of src.</p>
```<code>with open(f"assets/{filename}", "r") as f:
    html_content =  f.read()

content = html.Iframe(srcDoc=f"{html_content}", style={"height": "1067px", "width": "98%"})
</code>```

Body:
The idea is to display .html file in html.iFrame in Plotly Dash hosted in Kubernetes.

The code works as intended in local however it's met with 404 ( in K8s log ) when trying to fetch the file in the pod (/project/assets/). I have went into the pod to check and the files are there. I have checked for file permissions and they are the same as local (-rw-r--r--), parents folders have the same permissions too. I have some other files in /project/cache folders that can be successfully displayed through dcc.Graph indicating that io is fine.

100.64.109.71 - - [04/Feb/2022 02:41:58] "POST /_dash-update-component HTTP/1.1" 200 -
100.64.109.71 - - [04/Feb/2022 02:41:58] "GET /assets/country/datetime/filename.html HTTP/1.1" 404 -

Is there something unique about html.iFrame in Kubernetes that I have missed out? My apologies if the question is too terse but I am not even sure where or how to start debugging.

Update 1: Found useful reference ( https://github.com/plotly/dash/issues/489 )

Body:
Solved using srcDoc instead of src.

with open(f"assets/{filename}", "r") as f:
    html_content =  f.read()

content = html.Iframe(srcDoc=f"{html_content}", style={"height": "1067px", "width": "98%"})


问:
LARK: Parsing : Implementing import file?
How would you implement a grammar that can import a file and still parsing it using LARK ?

f.e.:

```<code>@import file.txt
.....
</code>```

答:
the [code at this link][1] will do includes / import in lark. I didn't write this, just passing it on.

it still needs some tweaking for error handling, but it's a good place to start.

below is my slight modifications to it, it actually reads from the files.

```<code>import sys

from lark import Lark

from lark.lexer import Lexer, LexerState, LexerThread

class RecursiveLexerThread(LexerThread):

    def __init__(self, lexer: Lexer, lexer_state):
        self.lexer = lexer
        self.state_stack = [lexer_state]

    def lex(self, parser_state):
        while self.state_stack:
            lexer_state = self.state_stack[-1]
            lex = self.lexer.lex(lexer_state, parser_state)
            try:
                token = next(lex)
            except StopIteration:
                self.state_stack.pop()  # We are done with this file
            else:
                if token.type == "_INCLUDE":
                    name = token.value[8:].strip()  # get just the filename
                    self.state_stack.append(LexerState(open(name).read()))
            yield token  # The parser still expects this token either way

grammar = r"""
start: ((_INCLUDE|line)* _EOL)*

line: STRING+
STRING : /\S+/

_INCLUDE.1 : /include\s+\S+/i

_EOL : /(\n+)/

%ignore /[ \t]+/
"""

parser = Lark(grammar, _plugins={
    "LexerThread": RecursiveLexerThread
}, parser="lalr")

tree = parser.parse(open(sys.argv[1]).read())

print(tree.pretty())

</code>```

https://gist.github.com/MegaIng/c6abba4d9be87473d8d586734f2b39c9

Body:
How would you implement a grammar that can import a file and still parsing it using LARK ?

f.e.:

@import file.txt
.....

Body:
the [code at this link][1] will do includes / import in lark. I didn't write this, just passing it on.

it still needs some tweaking for error handling, but it's a good place to start.

below is my slight modifications to it, it actually reads from the files.

import sys

from lark import Lark

from lark.lexer import Lexer, LexerState, LexerThread

class RecursiveLexerThread(LexerThread):

    def __init__(self, lexer: Lexer, lexer_state):
        self.lexer = lexer
        self.state_stack = [lexer_state]

    def lex(self, parser_state):
        while self.state_stack:
            lexer_state = self.state_stack[-1]
            lex = self.lexer.lex(lexer_state, parser_state)
            try:
                token = next(lex)
            except StopIteration:
                self.state_stack.pop()  # We are done with this file
            else:
                if token.type == "_INCLUDE":
                    name = token.value[8:].strip()  # get just the filename
                    self.state_stack.append(LexerState(open(name).read()))
            yield token  # The parser still expects this token either way

grammar = r"""
start: ((_INCLUDE|line)* _EOL)*

line: STRING+
STRING : /\S+/

_INCLUDE.1 : /include\s+\S+/i

_EOL : /(\n+)/

%ignore /[ \t]+/
"""

parser = Lark(grammar, _plugins={
    "LexerThread": RecursiveLexerThread
}, parser="lalr")

tree = parser.parse(open(sys.argv[1]).read())

print(tree.pretty())

https://gist.github.com/MegaIng/c6abba4d9be87473d8d586734f2b39c9


问:
How can I create a single dictionary from a text file that contains multiple individual JSON strings?
I have a dataset:

```<code>{ "source_table": "College", "action": "INSERT", "timestamp": "001", "name": "UT", "status": "1" }
{ "source_table": "Major",  "action": "INSERT", "timestamp": "003", "name": "Engineering"}
{ "source_table": "Class", "action": "UPDATE", "timestamp": "003", "name": "Freshman", "status": "1" }
{ "source_table": "Student", "action": "INSERT", "timestamp": "004", "state": "CA", "status": "1" }
{ "source_table": "Student", "action": "UPDATE", "timestamp": "007", "state": "TX", "status": "2" }
</code>```

My question is, since these are individually formatted strings, can they be loaded into a single dictionary? Or do they have to be sorted into different dictionaries, with each having the correct number of key/value pairs - i.e., college would source_table, action, timestamp, name, and status while student would have source_table, action, timestamp, state, and status?

I can read the file as a txt file (which it is - but is that correct?) Or does it need to be parsed as JSON from the txt file?

答:
You need to do them line by line.  Like this:

```<code>import json
data = []
for line in open('file.json'):
    data.append( json.loads(line) )
</code>```

Or:

```<code>data = [json.loads(line) for line in open('file.json')]
</code>```

Body:
I have a dataset:

{ "source_table": "College", "action": "INSERT", "timestamp": "001", "name": "UT", "status": "1" }
{ "source_table": "Major",  "action": "INSERT", "timestamp": "003", "name": "Engineering"}
{ "source_table": "Class", "action": "UPDATE", "timestamp": "003", "name": "Freshman", "status": "1" }
{ "source_table": "Student", "action": "INSERT", "timestamp": "004", "state": "CA", "status": "1" }
{ "source_table": "Student", "action": "UPDATE", "timestamp": "007", "state": "TX", "status": "2" }

My question is, since these are individually formatted strings, can they be loaded into a single dictionary? Or do they have to be sorted into different dictionaries, with each having the correct number of key/value pairs - i.e., college would source_table, action, timestamp, name, and status while student would have source_table, action, timestamp, state, and status?

I can read the file as a txt file (which it is - but is that correct?) Or does it need to be parsed as JSON from the txt file?

Body:
You need to do them line by line.  Like this:

import json
data = []
for line in open('file.json'):
    data.append( json.loads(line) )

Or:

data = [json.loads(line) for line in open('file.json')]


问:
How to trigger redraw of Xamarin BindableLayout
I have a BindableLayout that uses a List<PricingLevel> as the datasource. One of the columns in the resulting layout uses a converter to derive a calculated result based on a unit price in the view model and the PricingLevel property of the datasource.

```<code>public bool IsTaxInclusive { get; set; }
public decimal UnitPrice { get; set; }
public List<PricingLevel> PricingLevels { get; set; }
</code>```

If the IsTaxInclusive flag is switched I need to update the calculated results (note  PropertyChanged events are raised). But because the PricingLevels don't change, I'm not sure how to trigger the update. At the moment I just refresh the PricingLevels list which works but is not ideal. Is there a simple way to force the update?

答:
So the fix was simple. Rather than refresh the entire list, I used a FastObservableCollection and called its RaiseCollectionChanged() method.

```<code>public FastObservableCollection<PricingLevel> PricingLevels { get; set; }
...
PricingLevels.RaiseCollectionChanged();
</code>```

Body:
I have a BindableLayout that uses a List<PricingLevel> as the datasource. One of the columns in the resulting layout uses a converter to derive a calculated result based on a unit price in the view model and the PricingLevel property of the datasource.

public bool IsTaxInclusive { get; set; }
public decimal UnitPrice { get; set; }
public List<PricingLevel> PricingLevels { get; set; }

If the IsTaxInclusive flag is switched I need to update the calculated results (note  PropertyChanged events are raised). But because the PricingLevels don't change, I'm not sure how to trigger the update. At the moment I just refresh the PricingLevels list which works but is not ideal. Is there a simple way to force the update?

Body:
So the fix was simple. Rather than refresh the entire list, I used a FastObservableCollection and called its RaiseCollectionChanged() method.

public FastObservableCollection<PricingLevel> PricingLevels { get; set; }
...
PricingLevels.RaiseCollectionChanged();


问:
How to return a webpage containing images using spring?
I am just getting started with spring and have used their spring initialiser to create a project. I then tweaked the java code to get it do what I wanted:

The above method maps a GET request to the location "/hello/{name" to the method I have written which returns a string: 'Hello {name}". I want an image to be returned next to this; how would I go about this?

答:
This is not a common recommended approach. But since your question is to serve and HTML page with image via HTTP API, a very basic example is given below. Here the first API uses the second one internally to server the image. The image is served from resources folder and expecting that there is an image available with given name.
Note that you need to use proper MediaType for response Content-Type

```<code>@Controller
public class TestController {
    @GetMapping(value = "/hello/{name}", produces = MediaType.TEXT_HTML_VALUE)
    @ResponseBody
    public String hello(@PathVariable("name") String name) {
       return "<html>\n" + "<header><title>Hello "+name+"</title></header>\n" +
            "<body>\n" + "Hello \n" +name+ "<img src='http://localhost:8080/image?name="+name+"'/></body>\n" + "</html>";
    }
@GetMapping(
        value = "/image",
        produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(@RequestParam(value = "name") final String name) throws IOException {
    //Get Image using name
    var image= new ClassPathResource(name+".png");
    return  ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}
}
</code>```

Now you can access this even via browser pointing to http://<host:port/hello/{name}. This will display the HTML page with the image.

If you want to get image via API, then you need to get the resource and return MediaType IMAGE_PNG_VALUE (If the image is PNG file).
Example:

```<code> @GetMapping(
        value = "/image",
        produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(@RequestParam(value = "name") final String name) throws IOException {
    //Get Image using name
    var image= new ClassPathResource(name+".png");
    return  ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}
</code>```

Body:
This is not a common recommended approach. But since your question is to serve and HTML page with image via HTTP API, a very basic example is given below. Here the first API uses the second one internally to server the image. The image is served from resources folder and expecting that there is an image available with given name.
Note that you need to use proper MediaType for response Content-Type

@Controller
public class TestController {
    @GetMapping(value = "/hello/{name}", produces = MediaType.TEXT_HTML_VALUE)
    @ResponseBody
    public String hello(@PathVariable("name") String name) {
       return "<html>\n" + "<header><title>Hello "+name+"</title></header>\n" +
            "<body>\n" + "Hello \n" +name+ "<img src='http://localhost:8080/image?name="+name+"'/></body>\n" + "</html>";
    }
@GetMapping(
        value = "/image",
        produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(@RequestParam(value = "name") final String name) throws IOException {
    //Get Image using name
    var image= new ClassPathResource(name+".png");
    return  ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}
}

Now you can access this even via browser pointing to http://<host:port/hello/{name}. This will display the HTML page with the image.

If you want to get image via API, then you need to get the resource and return MediaType IMAGE_PNG_VALUE (If the image is PNG file).
Example:

 @GetMapping(
        value = "/image",
        produces = MediaType.IMAGE_PNG_VALUE
)
public ResponseEntity<InputStreamResource> getFile(@RequestParam(value = "name") final String name) throws IOException {
    //Get Image using name
    var image= new ClassPathResource(name+".png");
    return  ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(new InputStreamResource(image.getInputStream()));
}


问:
"-bash: //MacOS/Electron: No such file or directory" when using VS Code using " . code " shortcut
My IDE is VS Code
I have been using it many times
suddenly when I open vs code in my terminal

. code or source code

it displays error

```<code>-bash: //MacOS/Electron: No such file or directory
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
</code>```

[Process completed]

How do I fix this? I just want to get my normal vs code to work functional again just as before

答:
For me, I didn't have a globally accessible python. Which is called in /usr/local/bin/code.

Since I'm using asdf I simply did asdf global python x.xx.x.
If you are not using asdf perhaps perform brew install python.

Body:
My IDE is VS Code
I have been using it many times
suddenly when I open vs code in my terminal

. code or source code

it displays error

-bash: //MacOS/Electron: No such file or directory
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.

[Process completed]

How do I fix this? I just want to get my normal vs code to work functional again just as before


问:
Twilio Redirecting the wrong call when using CallSid and trying to update live call
So here's the logic of what I am working on:

Someone calls my Twilio Number I use the dial twiml to forward to a cell phone

I use gather and play a whisper to the operator answering the phone (so his cell phone).

The operator has a choice - press 1 to accept, press 2 (transfers to
a different agent).

step 3 is where I am having trouble I am using the code below:

```<code>$call = $twilio->calls($CallSid)
           ->update([
                        "method" => "POST",
                        "url" => "http:www.example.com/directcall.php"
                    ]
           );
</code>```

Here's the problem it is modifying the call but it's redirecting the operators phone number instead of the person who is calling in. So the operator is getting redirected to the other operator and the customer is being hung up on. I tried using the parentcallsid too but that doesn't seem to work either.

Any ideas what I am doing wrong?

so just to be clear I want the flow to work like this:

Customer calls phone number -> redirects to designated operator -> if designated operator presses 2 it redirects the customer to operator 2 and disconnects operator 1 from the call. Is this possible?

Thanks for the help, I greatly appreciate it.

UPDATE PLEASE FIND THE CODE SAMPLES BELOW

Index.php

<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$twilionumber = ltrim($_POST['To'], '+');
$callernumber=ltrim($_POST['From'], '+');

createCall($phonenumbertouse,$response,$twilionumber);

echo $response;

function createCall($phonenumbertouse,$response,$twilionumber) {

$dial = $response->dial('',['timeout' => '30']);

    $dial->number($phonenumbertouse, ['action' => "http://example.com/whisper.php",'method' => 'GET']);

}

```
<p><strong>WHISPER.PHP</strong></p>
<pre class="lang-php prettyprint-override"><code>
<?php
include ("config.php");

require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$gather = $response->gather(['action' => "http://example.com/route.php",
    'method' => 'GET']);
$gather->say($whisper, ['voice' => 'woman', 'language' => 'en-US']);

echo $response;

?>
</code>```

route.php

<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;
use Twilio\Rest\Client;
$response = new VoiceResponse();
$keyedInput=$_REQUEST['Digits'];
$mycallsid=$_REQUEST['ParentCallSid'];

if ($keyedInput == 1){
     $response->say('connecting the call');
}
elseif ($keyedInput == 2){
    $twilio = new Client($sid, $token);
    $call = $twilio->calls($mycallsid)
                   ->update([
                                "method" => "POST",
                                "url" => "http://example.com/redirect.php"
                            ]
                   );

}

elseif  ($keyedInput == 3){
        $response->say('you selected 3');

}
else  {
        $response->say('Sorry, I don\'t understand that choice.');

    }

 echo $response;

?>

```
<p>**Redirect.php **</p>
<pre class="lang-php prettyprint-override"><code>
<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$dial = $response->dial('+14151234567',['timeout' => '30']);

echo $response;

?>

</code>```

答:
Twilio developer evangelist here.

Your issue here is that you are using the wrong CallSid to update.

In this case there are two CallSids at play. When your user dials in to your Twilio number, that call between the user and Twilio has one CallSid. Then, when Twilio creates an outbound call to the operator, that call has a different CallSid.

In your application, when you get the <Gather> response from the operator, the CallSid being sent to your endpoint is the CallSid of the operator's call leg. Instead, you need to find the CallSid of the original call.

You should find that the ParentCallSid parameter is sent to the webhook endpoint as well. That ParentCallSid is the original inbound call's Sid and is what you should use to redirect the caller to another operator.

Edit

OK, so I had a go at building this. I don't normally work in PHP, so I wrote this in Node.js (as Twilio Functions). I got it to work and the answer still seems to me to be "use the ParentCallSid, so hopefully it gives you some idea where you might have gone wrong.

The incoming call

This makes an outbound call to my cell phone number, with a url set to make the whisper to me when I answer the call.

exports.handler = function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  const dial = twiml.dial();
  dial.number({ url: "/whisper" }, MY_CELL_PHONE_NUMBER);
  callback(null, twiml);
};
```
<pre class="lang-xml prettyprint-override"><code><Response>
  <Dial><Number url="/whisper">MY_CELL_PHONE_NUMBER</Number></Dial>
</Response>
</code>```

The whisper

This returns a <Gather> spoken to the person answering the cell phone number. It offers a choice, dial "1" to connect or "2" to hang up, triggering the original caller to dial to another number.

exports.handler = function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  const gather = twiml.gather({ digits: 1, action: "/after-whisper" });
  gather.say("Dial 1 to connect, dial 2 to hang up.");
  callback(null, twiml);
};
```
<pre class="lang-xml prettyprint-override"><code><Response>
  <Gather action="/after-whisper" digits="1">
    <Say>Dial 1 to connect, dial 2 to hang up.</Say>
  </Gather>
</Response>
</code>```

The Gather action "/after-whisper"

This checks the Digits parameter. If it is "1" it immediately calls back with an empty response, signalling the end of the whisper and leading the call to connect with the original caller.

If the Digits parameter is not "1" then we initialise a Twilio client and make a request to the API to update the call with the sid ParentCallSid to a new URL. Once that is complete we return TwiML that says to <Hangup> the whisper call (which wasn't strictly necessary, but I like the intention).

exports.handler = async function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  if (event.Digits === "1") {
    callback(null, twiml);
  } else {
    const client = context.getTwilioClient();
    try {
      // Update the parent call with a new URL.
      await client.calls(event.ParentCallSid).update({
        url: URL_TO_NEXT_TWIML,
      });
    } catch (error) {
      console.log(error);
    }
    twiml.hangup();
    callback(null, twiml);
  }
};
```
<h4>The next TwiML</h4>
<p>This is the endpoint that the <code>url</code> above relates to, when it gets the callback it just returns a <code><Dial></code> to another number, though it could include another whisper and go round this loop again if desired.</p>
<pre class="lang-js prettyprint-override"><code>exports.handler = async function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();

  twiml.dial(NEXT_NUMBER_TO_DIAL);
  callback(null, twiml);
};
</code>```

<Response>
  <Dial>NEXT_NUMBER_TO_DIAL</Dial>
</Response>
```

Body:
So here's the logic of what I am working on:

Someone calls my Twilio Number I use the dial twiml to forward to a cell phone

I use gather and play a whisper to the operator answering the phone (so his cell phone).

The operator has a choice - press 1 to accept, press 2 (transfers to
a different agent).

step 3 is where I am having trouble I am using the code below:

$call = $twilio->calls($CallSid)
           ->update([
                        "method" => "POST",
                        "url" => "http:www.example.com/directcall.php"
                    ]
           );

Here's the problem it is modifying the call but it's redirecting the operators phone number instead of the person who is calling in. So the operator is getting redirected to the other operator and the customer is being hung up on. I tried using the parentcallsid too but that doesn't seem to work either.

Any ideas what I am doing wrong?

so just to be clear I want the flow to work like this:

Customer calls phone number -> redirects to designated operator -> if designated operator presses 2 it redirects the customer to operator 2 and disconnects operator 1 from the call. Is this possible?

Thanks for the help, I greatly appreciate it.

UPDATE PLEASE FIND THE CODE SAMPLES BELOW

Index.php

<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$twilionumber = ltrim($_POST['To'], '+');
$callernumber=ltrim($_POST['From'], '+');

createCall($phonenumbertouse,$response,$twilionumber);

echo $response;

function createCall($phonenumbertouse,$response,$twilionumber) {

$dial = $response->dial('',['timeout' => '30']);

    $dial->number($phonenumbertouse, ['action' => "http://example.com/whisper.php",'method' => 'GET']);

}

WHISPER.PHP

<?php
include ("config.php");

require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$gather = $response->gather(['action' => "http://example.com/route.php",
    'method' => 'GET']);
$gather->say($whisper, ['voice' => 'woman', 'language' => 'en-US']);

echo $response;

?>

route.php

<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;
use Twilio\Rest\Client;
$response = new VoiceResponse();
$keyedInput=$_REQUEST['Digits'];
$mycallsid=$_REQUEST['ParentCallSid'];

if ($keyedInput == 1){
     $response->say('connecting the call');
}
elseif ($keyedInput == 2){
    $twilio = new Client($sid, $token);
    $call = $twilio->calls($mycallsid)
                   ->update([
                                "method" => "POST",
                                "url" => "http://example.com/redirect.php"
                            ]
                   );

}

elseif  ($keyedInput == 3){
        $response->say('you selected 3');

}
else  {
        $response->say('Sorry, I don\'t understand that choice.');

    }

 echo $response;

?>

**Redirect.php **

<?php
include ("config.php");
require_once './vendor/autoload.php';
use Twilio\TwiML\VoiceResponse;

$response = new VoiceResponse();

$dial = $response->dial('+14151234567',['timeout' => '30']);

echo $response;

?>

Body:
Twilio developer evangelist here.

Your issue here is that you are using the wrong CallSid to update.

In this case there are two CallSids at play. When your user dials in to your Twilio number, that call between the user and Twilio has one CallSid. Then, when Twilio creates an outbound call to the operator, that call has a different CallSid.

In your application, when you get the <Gather> response from the operator, the CallSid being sent to your endpoint is the CallSid of the operator's call leg. Instead, you need to find the CallSid of the original call.

You should find that the ParentCallSid parameter is sent to the webhook endpoint as well. That ParentCallSid is the original inbound call's Sid and is what you should use to redirect the caller to another operator.

Edit

OK, so I had a go at building this. I don't normally work in PHP, so I wrote this in Node.js (as Twilio Functions). I got it to work and the answer still seems to me to be "use the ParentCallSid, so hopefully it gives you some idea where you might have gone wrong.

The incoming call

This makes an outbound call to my cell phone number, with a url set to make the whisper to me when I answer the call.

exports.handler = function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  const dial = twiml.dial();
  dial.number({ url: "/whisper" }, MY_CELL_PHONE_NUMBER);
  callback(null, twiml);
};

<Response>
  <Dial><Number url="/whisper">MY_CELL_PHONE_NUMBER</Number></Dial>
</Response>

The whisper

This returns a <Gather> spoken to the person answering the cell phone number. It offers a choice, dial "1" to connect or "2" to hang up, triggering the original caller to dial to another number.

exports.handler = function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  const gather = twiml.gather({ digits: 1, action: "/after-whisper" });
  gather.say("Dial 1 to connect, dial 2 to hang up.");
  callback(null, twiml);
};

<Response>
  <Gather action="/after-whisper" digits="1">
    <Say>Dial 1 to connect, dial 2 to hang up.</Say>
  </Gather>
</Response>

The Gather action "/after-whisper"

This checks the Digits parameter. If it is "1" it immediately calls back with an empty response, signalling the end of the whisper and leading the call to connect with the original caller.

If the Digits parameter is not "1" then we initialise a Twilio client and make a request to the API to update the call with the sid ParentCallSid to a new URL. Once that is complete we return TwiML that says to <Hangup> the whisper call (which wasn't strictly necessary, but I like the intention).

exports.handler = async function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();
  if (event.Digits === "1") {
    callback(null, twiml);
  } else {
    const client = context.getTwilioClient();
    try {
      // Update the parent call with a new URL.
      await client.calls(event.ParentCallSid).update({
        url: URL_TO_NEXT_TWIML,
      });
    } catch (error) {
      console.log(error);
    }
    twiml.hangup();
    callback(null, twiml);
  }
};

The next TwiML

This is the endpoint that the url above relates to, when it gets the callback it just returns a <Dial> to another number, though it could include another whisper and go round this loop again if desired.

exports.handler = async function (context, event, callback) {
  const twiml = new Twilio.twiml.VoiceResponse();

  twiml.dial(NEXT_NUMBER_TO_DIAL);
  callback(null, twiml);
};

<Response>
  <Dial>NEXT_NUMBER_TO_DIAL</Dial>
</Response>


问:
Countdown won't stop at 0, keeps decrementing
I have a timer that keeps decrementing after 0 so I get negative numbers. Time starts when a button is clicked and the pauses when the same button is clicked again.

```<code>button.addEventListener("click", function(event){
    console.log('timer started')
    // Timer paused, click to start

            // Pause/Play Timer
            if(timeleft == 90){
                timeleft = setInterval(function() {
                    time--;
                    timerDisplay.innerHTML = time;
                }, 1000);
            } else if (timeleft === 0) {
                clearInterval(timeleft);
            } else{
            // Timer running, click to pause
              console.log('timer paused')
                clearInterval(timeleft);
                timeleft = 90;
            }
        });
</code>```

The stop and start functionality works fine but why won't it stop counting down once it reaches 0?

答:
Sample code for reference to build a timer.

const actionBtn = document.getElementById("start-timer");
let isTimerRunning =  false;
let interval = null;
let maxTime = 20;

// Click handler to start and stop timer button in DOM
actionBtn.addEventListener("click", function() {
  if(isTimerRunning) {
    // stop timer
    stopTimer();
  } else {
    // start timer
    startTimer();
  }
});

// Function to start timer
function startTimer() {
  isTimerRunning = true; // toggle state, so on click again we can stop timer
  // 1sec interval function to reduce max time
  interval = setInterval(function() {
    maxTime = maxTime - 1;
    if(maxTime > -1) { // if the more time left (more than 0) update UI
      renderUi(`Reset (${maxTime}sec)`);
    } else { // if there is no time left stop timer
      stopTimer();
    }
  }, 1000);
}

// stop timer
function stopTimer() {
  isTimerRunning = false; // toggle state, so on click again we can start timer
  clearInterval(interval); // clear the interval
  maxTime = 20; // reset max time to initial value
  renderUi(`Start Timer (${maxTime}sec)`); // update UI to initial value
}

// A generic function to update UI
// if we have complet UI structure we can update this function
function renderUi(str) {
  actionBtn.innerText = str;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><button id="start-timer">Start Timer (20sec)</button></code>```

Body:
I have a timer that keeps decrementing after 0 so I get negative numbers. Time starts when a button is clicked and the pauses when the same button is clicked again.

button.addEventListener("click", function(event){
    console.log('timer started')
    // Timer paused, click to start

            // Pause/Play Timer
            if(timeleft == 90){
                timeleft = setInterval(function() {
                    time--;
                    timerDisplay.innerHTML = time;
                }, 1000);
            } else if (timeleft === 0) {
                clearInterval(timeleft);
            } else{
            // Timer running, click to pause
              console.log('timer paused')
                clearInterval(timeleft);
                timeleft = 90;
            }
        });

The stop and start functionality works fine but why won't it stop counting down once it reaches 0?

Body:
Sample code for reference to build a timer.

const actionBtn = document.getElementById("start-timer");
let isTimerRunning =  false;
let interval = null;
let maxTime = 20;

// Click handler to start and stop timer button in DOM
actionBtn.addEventListener("click", function() {
  if(isTimerRunning) {
    // stop timer
    stopTimer();
  } else {
    // start timer
    startTimer();
  }
});

// Function to start timer
function startTimer() {
  isTimerRunning = true; // toggle state, so on click again we can stop timer
  // 1sec interval function to reduce max time
  interval = setInterval(function() {
    maxTime = maxTime - 1;
    if(maxTime > -1) { // if the more time left (more than 0) update UI
      renderUi(`Reset (${maxTime}sec)`);
    } else { // if there is no time left stop timer
      stopTimer();
    }
  }, 1000);
}

// stop timer
function stopTimer() {
  isTimerRunning = false; // toggle state, so on click again we can start timer
  clearInterval(interval); // clear the interval
  maxTime = 20; // reset max time to initial value
  renderUi(`Start Timer (${maxTime}sec)`); // update UI to initial value
}

// A generic function to update UI
// if we have complet UI structure we can update this function
function renderUi(str) {
  actionBtn.innerText = str;
}

<button id="start-timer">Start Timer (20sec)</button>


问:
How can I set the range for a horizontal list to be captured in a dictionary
found this helpful code to compare two lists and then extract any missing item from List 1 that is not in List 2.

Issue I have is to set the range for the second since the list is horizontal not vertically structured. the code line "Set rgCompare = Worksheets("Dashboard_Data").Range("B1:b100")" is supposed to capture B1:CF1. When I enter that range, I get everything in List 1 listed as "not in List 2"

```<code>Option Explicit

' Description: Use to determine the result type required
Public Enum eResultType
    list1Only = 1
    both = 2
    list2Only = 3
End Enum

' Source worksheet: Data (can be changed in the get ranges section below)
' Destination worksheet: Data (can be changed in the get ranges section below)
Sub MainCompare()

' Set the result type to both or list 1 only
   Dim resultType As eResultType
   resultType = eResultType.list1Only

' Get the ranges
    Dim rgBase As Range, rgCompare As Range, rgResult As Range
    Set rgBase = Worksheets("Ref").Range("Dashboard_Headers")
    Set rgCompare = Worksheets("Dashboard_Data").Range("B1:b100")
    Set rgResult = Worksheets("Error").Range("D1")

' Read the first list to a Dictionary
    Dim dictBase As Dictionary
    Set dictBase = ReadList(rgBase.Value)

' Compare the Dictionary to the second list
    Dim dictResult As Dictionary
    Set dictResult = CompareLists(dictBase, rgCompare.Value, resultType)

' Write out the result
    Call WriteResult(rgResult, dictResult, resultType)

End Sub

' Name: ReadList()
' Description: Reads the first list of data to a dictionary. Note that
' all duplicates are removed.
' Input: array of data taken from the worksheet
' Output: a dictionary of unique values
Public Function ReadList(arr As Variant) As Dictionary

Dim dict As New Dictionary

Dim i As Long
For i = LBound(arr, 1) + 1 To UBound(arr, 1)
    dict(arr(i, 1)) = 0
Next i

' Read through the list
    Set ReadList = dict

End Function

' Name: CompareLists()
' Description: Read through a list of data and check if in the dictionary which
' contains the values from the first list
' Input: Dictionary of the first list and array of the second list
' Output: A dictionary of the results

Function CompareLists(dict As Dictionary _
                , arrCompareTo As Variant _
                , Optional resultType As eResultType = eResultType.both) As Dictionary

Dim dictBoth As New Dictionary, dictList2 As New Dictionary

Dim i As Long, item As Variant
For i = LBound(arrCompareTo) To UBound(arrCompareTo)
    item = arrCompareTo(i, 1)
    If dict.Exists(item) = True Then
        dictBoth(item) = 0
        dict.Remove item
    Else
        dictList2(item) = 0
    End If
Next i

If resultType = both Then
    Set CompareLists = dictBoth
ElseIf resultType = list1Only Then
    Set CompareLists = dict
ElseIf resultType = list2Only Then
    Set CompareLists = dictList2
End If

End Function

' Name: WriteResult()
' Description: Writes out the values from the results dictionary to the worksheet
' Input: Output range, dictionary of data to write, the result type
' Author: Paul Kelly
' https://ExcelMacroMastery.com/
' YouTube video: https://youtu.be/P_UVvYW2xto
Public Sub WriteResult(rg As Range, dict As Dictionary, resultType As eResultType)

' Clear existing data
rg.CurrentRegion.OffSet(1).ClearContents

' Write out list
rg.OffSet(1).Resize(dict.Count, 1).Value = WorksheetFunction.Transpose(dict.Keys)

End Sub
</code>```

答:
if rgCompare is set to a horizontal range, eg B1:CF1, then change the set dictResult as follows:

```<code>Set dictResult = CompareLists(dictBase, Application.Transpose(rgCompare.Value), resultType)
</code>```

This will switch the array to the orientation the CompareLists function is expecting.

Body:
found this helpful code to compare two lists and then extract any missing item from List 1 that is not in List 2.

Issue I have is to set the range for the second since the list is horizontal not vertically structured. the code line "Set rgCompare = Worksheets("Dashboard_Data").Range("B1:b100")" is supposed to capture B1:CF1. When I enter that range, I get everything in List 1 listed as "not in List 2"

Option Explicit

' Description: Use to determine the result type required
Public Enum eResultType
    list1Only = 1
    both = 2
    list2Only = 3
End Enum

' Source worksheet: Data (can be changed in the get ranges section below)
' Destination worksheet: Data (can be changed in the get ranges section below)
Sub MainCompare()

' Set the result type to both or list 1 only
   Dim resultType As eResultType
   resultType = eResultType.list1Only

' Get the ranges
    Dim rgBase As Range, rgCompare As Range, rgResult As Range
    Set rgBase = Worksheets("Ref").Range("Dashboard_Headers")
    Set rgCompare = Worksheets("Dashboard_Data").Range("B1:b100")
    Set rgResult = Worksheets("Error").Range("D1")

' Read the first list to a Dictionary
    Dim dictBase As Dictionary
    Set dictBase = ReadList(rgBase.Value)

' Compare the Dictionary to the second list
    Dim dictResult As Dictionary
    Set dictResult = CompareLists(dictBase, rgCompare.Value, resultType)

' Write out the result
    Call WriteResult(rgResult, dictResult, resultType)

End Sub

' Name: ReadList()
' Description: Reads the first list of data to a dictionary. Note that
' all duplicates are removed.
' Input: array of data taken from the worksheet
' Output: a dictionary of unique values
Public Function ReadList(arr As Variant) As Dictionary

Dim dict As New Dictionary

Dim i As Long
For i = LBound(arr, 1) + 1 To UBound(arr, 1)
    dict(arr(i, 1)) = 0
Next i

' Read through the list
    Set ReadList = dict

End Function

' Name: CompareLists()
' Description: Read through a list of data and check if in the dictionary which
' contains the values from the first list
' Input: Dictionary of the first list and array of the second list
' Output: A dictionary of the results

Function CompareLists(dict As Dictionary _
                , arrCompareTo As Variant _
                , Optional resultType As eResultType = eResultType.both) As Dictionary

Dim dictBoth As New Dictionary, dictList2 As New Dictionary

Dim i As Long, item As Variant
For i = LBound(arrCompareTo) To UBound(arrCompareTo)
    item = arrCompareTo(i, 1)
    If dict.Exists(item) = True Then
        dictBoth(item) = 0
        dict.Remove item
    Else
        dictList2(item) = 0
    End If
Next i

If resultType = both Then
    Set CompareLists = dictBoth
ElseIf resultType = list1Only Then
    Set CompareLists = dict
ElseIf resultType = list2Only Then
    Set CompareLists = dictList2
End If

End Function

' Name: WriteResult()
' Description: Writes out the values from the results dictionary to the worksheet
' Input: Output range, dictionary of data to write, the result type
' Author: Paul Kelly
' https://ExcelMacroMastery.com/
' YouTube video: https://youtu.be/P_UVvYW2xto
Public Sub WriteResult(rg As Range, dict As Dictionary, resultType As eResultType)

' Clear existing data
rg.CurrentRegion.OffSet(1).ClearContents

' Write out list
rg.OffSet(1).Resize(dict.Count, 1).Value = WorksheetFunction.Transpose(dict.Keys)

End Sub

Body:
if rgCompare is set to a horizontal range, eg B1:CF1, then change the set dictResult as follows:

Set dictResult = CompareLists(dictBase, Application.Transpose(rgCompare.Value), resultType)

This will switch the array to the orientation the CompareLists function is expecting.


问:
What does '&' do in C/C++ and what is its equivalent operator in perl?
I'm writing a perl implementation of a protocol whose specification is given for C/C++ but I don't know much C.

What does the condition if ((flags & 0x400) != 0) mean? How do I do that in perl?

Is if ($flags == "\x400") correct?

答: It's the bitwise AND. In Perl, the operator is "&" as well.</p>