问:
How to get download URL of multiple images uploaded using Android & Firebase
I see similar questions on this site but most of the questions are related to fetching the download URL for a single uploaded image. Taking help from those posts, now I can get the download URL of a single image.

But I face a problem when I try to get download URL for multiple images uploaded together. I want to do three things...

1. Select three images

  2. Upload them to Firebase Cloud Storage

  3. Get the URLs of the uploaded images and save them in an ArrayList.

I can do the first two things successfully, but have not managed to achieve the third thing. When I click the "update" button, all images are perfectly stored in Cloud Storage, but show an error when requesting the download URL of all images.

Here is the code for when I click the "update" button:

```<code>upload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        progressDialog.setMessage("Uploading .... ");
        progressDialog.show();

        storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");

        int uploadCount = 0;

        // imageList is an ArrayList<Uri> which holds the address of selected 3 images.
        // imageAddress is an ArrayList<String> where I want to save all downloadUrls of images (each url is saved as a string).
        // imagePath is a StorageReference

        while(uploadCount < imageList.size()) {
            Log.d("UploadCount", uploadCount+"");
            Uri uri_Image = imageList.get(uploadCount);
            imagePath = storageReference.child(uri_Image.getLastPathSegment());

            imagePath.putFile(uri_Image).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    imagePath.getDownloadUrl().addOnSuccessListener(newOnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            Uri downloadUri = uri;
                            imageAddress.add(downloadUri.toString());
                            Log.d("ImageAddress Size: ", imageAddress.size()+"");
                        }
                    });
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(SignOutActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                    progressDialog.dismiss();
                }
            }); //.............
            if(uploadCount == (imageList.size()-1)) {
                Log.d("Good", "HELLO HELLO");
                Toast.makeText(SignOutActivity.this, "Successfully Uploaded", Toast.LENGTH_LONG).show();
                upload.setClickable(false);
                progressDialog.dismiss();
            }
            else {
                Log.d("BAD", "NOT HELLO "+uploadCount);
            }
            uploadCount = uploadCount + 1;

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

Here is the error:

2020-02-15 17:02:26.945 28207-28735/com.example.practiceapplication E/StorageException: StorageException has occurred.
    Object does not exist at location.
    Code: -13010 HttpResult: 404
2020-02-15 17:02:26.946 28207-28735/com.example.practiceapplication E/StorageException: {"error": {"code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT"}}
    java.io.IOException: {"error": {"code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT"}}
        at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@19.1.1:433)
        at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@19.1.1:450)
        at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@19.1.1:441)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:272)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:286)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:70)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:62)
        at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage@@19.1.1:76)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
2020-02-15 17:02:30.712 28207-28207/com.example.practiceapplication D/ImageAddress Size:: 1
```

It will be very helpful to me if anyone tells me the correction. Thank you

答:
Your code suffers from using a mix of local variables and shared global variables whilst dealing with asynchronous code and for loops.

In the code above, you use the global variables imagePath, imageAddress and imageList inside a for loop which ultimately is the key cause of that Exception.

Code breakdown

When you click the upload button, your code performs the following steps with errors shown in bold:

Gets the first image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the first image

Logs "NOT HELLO 0"

Gets the second image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the second image

Logs "NOT HELLO 1"

Gets the third image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the third image

Logs "HELLO HELLO" and Toasts "Successfully Uploaded" (not actually finished yet)

[a few moments later]

The first image finishes uploading

The download URL of the third image is requested (which throws the StorageException)

The second image finishes uploading

The download URL of the third image is requested (which throws another StorageException)

The third image finishes uploading

The download URL of the third image is requested (and would work correctly)

Fixes

To fix this, the following things must be done:

Use a local variable copy of imageList

Use a local variable for storageReference

Use a local variable for imagePath, and rename to imageRef to accurately reflect it's type

Rename imageAddress to imageAddressList to accurately reflect it's type (recommended)

Remove the while() loop and use a for iterator instead

Disable the upload button immediately instead of at the end

Upload each image and fetch the download URLs in parallel, without conflicting with each other

Only display "Successfully uploaded" or "Upload failed" messages after the uploads have actually completed

Update imageAddressList only once, rather than asynchronously.

To be done:

Handle activity lifecycle changes

Tap into currentUploadTask and bind it to a view dialog/notification to show file upload progress

Update the UI once all the uploads are done

Updated code

Note: This was typed free-hand - expect a few typos.

```<code>upload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        progressDialog.setMessage("Uploading .... ");
        progressDialog.show();
        upload.setClickable(false); // disable upload button whilst uploading

        final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");
        final List<Uri> clonedImageList = new ArrayList<>(imageList);

        imageList.clear(); // empty old list?
        int imageListSize = clonedImageList.size();

        List<Task<Uri>> uploadedImageUrlTasks = new ArrayList<>(imageListSize);

        for (Uri imageUri : clonedImageList) {
            final String imageFilename = imageUri.getLastPathSegment();
            Log.d("upload.onClick()", "Starting upload for \"" + imageFilename + "\"...");

            StorageReference imageRef = storageReference.child(imageFilename); // Warning: potential for collisions/overwrite
            UploadTask currentUploadTask = imageRef.putFile(imageUri);

            Task<Uri> currentUrlTask = currentUploadTask
                .continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                    @Override
                    public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                        if (!task.isSuccessful()) {
                            Log.d("upload.onClick()", "Upload for \"" + imageFilename + "\" failed!");
                            throw task.getException(); // rethrow any errors
                        }

                        Log.d("upload.onClick()", "Upload for \"" + imageFilename + "\" finished. Fetching download URL...");
                        return imageRef.getDownloadUrl();
                    }
                })
                .continueWithTask(new Continuation<Uri, Uri>() { // purely for logging to debug, recommended to remove
                    @Override
                    public Task<Uri> then(@NonNull Task<Uri> task) throws Exception {
                        if (!task.isSuccessful()) {
                            Log.d("upload.onClick()", "Could not get download URL for \"" + imageFilename + "\"!");
                            throw task.getException(); // rethrow any errors
                        }

                        Log.d("upload.onClick()", "Download URL for \"" + imageFilename + "\" is \"" + task.getResult() + "\".");
                        return task.getResult();
                    }
                });

              uploadedImageUrlTasks.add(currentUrlTask);
        }

        // At this point, all the files are being uploaded in parallel
        // Each upload is tracked by the tasks in uploadedImageUrlTasks

        Tasks.whenAllComplete(uploadedImageUrlTasks)
            .addOnCompleteListener(new OnCompleteListener<List<Task<Uri>>>() {
                @Override
                public void onComplete(@NonNull List<Task<Uri>> tasks) {
                    int tasksCount = tasks.size();
                    List<Uri> failedUploads = new ArrayList<>();
                    imageAddressList.clear(); // empty old entries?

                    for (Task<Uri> task : tasks) {
                        if (task.isSuccessful()) {
                            successCount++;
                            Uri downloadUri = task.getResult();
                            imageAddressList.add(downloadUri.toString());
                        } else {
                            Uri imageUri = clonedImageList.get(tasks.indexOf(task));
                            failedUploads.add(imageUri);
                            Log.e("upload.onClick()", "Failed to upload/fetch URL for \"" + imageUri.getLastPathSegment() + "\" with exception", task.getException()); // log exception
                        }
                    }

                    progressDialog.dismiss(); // dismiss upload dialog

                    if (failedUploads.size() > 0) {
                        Toast.makeText(SignOutActivity.this, failedUploads.size() + "/" + tasksCount + " uploads failed.", Toast.LENGTH_LONG).show();
                        // TODO: Do something with list of failed uploads such as readd to the now empty upload list
                        imageList.addAll(failedUploads);
                        upload.setClickable(true);
                    } else {
                        Toast.makeText(SignOutActivity.this, "Successfully uploaded all " + tasksCount + " files.", Toast.LENGTH_LONG).show();
                    }

                    // TODO: Now that imageAddressList has been updated, update the UI - e.g tell recycler view to refresh
                }
            });
    }
});
</code>```

Body:
I see similar questions on this site but most of the questions are related to fetching the download URL for a single uploaded image. Taking help from those posts, now I can get the download URL of a single image.

But I face a problem when I try to get download URL for multiple images uploaded together. I want to do three things...

1. Select three images

  2. Upload them to Firebase Cloud Storage

  3. Get the URLs of the uploaded images and save them in an ArrayList.

I can do the first two things successfully, but have not managed to achieve the third thing. When I click the "update" button, all images are perfectly stored in Cloud Storage, but show an error when requesting the download URL of all images.

Here is the code for when I click the "update" button:

upload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        progressDialog.setMessage("Uploading .... ");
        progressDialog.show();

        storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");

        int uploadCount = 0;

        // imageList is an ArrayList<Uri> which holds the address of selected 3 images.
        // imageAddress is an ArrayList<String> where I want to save all downloadUrls of images (each url is saved as a string).
        // imagePath is a StorageReference

        while(uploadCount < imageList.size()) {
            Log.d("UploadCount", uploadCount+"");
            Uri uri_Image = imageList.get(uploadCount);
            imagePath = storageReference.child(uri_Image.getLastPathSegment());

            imagePath.putFile(uri_Image).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    imagePath.getDownloadUrl().addOnSuccessListener(newOnSuccessListener<Uri>() {
                        @Override
                        public void onSuccess(Uri uri) {
                            Uri downloadUri = uri;
                            imageAddress.add(downloadUri.toString());
                            Log.d("ImageAddress Size: ", imageAddress.size()+"");
                        }
                    });
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(SignOutActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
                    progressDialog.dismiss();
                }
            }); //.............
            if(uploadCount == (imageList.size()-1)) {
                Log.d("Good", "HELLO HELLO");
                Toast.makeText(SignOutActivity.this, "Successfully Uploaded", Toast.LENGTH_LONG).show();
                upload.setClickable(false);
                progressDialog.dismiss();
            }
            else {
                Log.d("BAD", "NOT HELLO "+uploadCount);
            }
            uploadCount = uploadCount + 1;

        }
    }
});

Here is the error:

2020-02-15 17:02:26.945 28207-28735/com.example.practiceapplication E/StorageException: StorageException has occurred.
    Object does not exist at location.
    Code: -13010 HttpResult: 404
2020-02-15 17:02:26.946 28207-28735/com.example.practiceapplication E/StorageException: {"error": {"code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT"}}
    java.io.IOException: {"error": {"code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT"}}
        at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage@@19.1.1:433)
        at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage@@19.1.1:450)
        at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage@@19.1.1:441)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:272)
        at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage@@19.1.1:286)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:70)
        at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage@@19.1.1:62)
        at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage@@19.1.1:76)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
2020-02-15 17:02:30.712 28207-28207/com.example.practiceapplication D/ImageAddress Size:: 1

It will be very helpful to me if anyone tells me the correction. Thank you

Body:
Your code suffers from using a mix of local variables and shared global variables whilst dealing with asynchronous code and for loops.

In the code above, you use the global variables imagePath, imageAddress and imageList inside a for loop which ultimately is the key cause of that Exception.

Code breakdown

When you click the upload button, your code performs the following steps with errors shown in bold:

Gets the first image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the first image

Logs "NOT HELLO 0"

Gets the second image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the second image

Logs "NOT HELLO 1"

Gets the third image's URI

Updates the value of imagePath to point at that image's upload location

Starts the upload of the third image

Logs "HELLO HELLO" and Toasts "Successfully Uploaded" (not actually finished yet)

[a few moments later]

The first image finishes uploading

The download URL of the third image is requested (which throws the StorageException)

The second image finishes uploading

The download URL of the third image is requested (which throws another StorageException)

The third image finishes uploading

The download URL of the third image is requested (and would work correctly)

Fixes

To fix this, the following things must be done:

Use a local variable copy of imageList

Use a local variable for storageReference

Use a local variable for imagePath, and rename to imageRef to accurately reflect it's type

Rename imageAddress to imageAddressList to accurately reflect it's type (recommended)

Remove the while() loop and use a for iterator instead

Disable the upload button immediately instead of at the end

Upload each image and fetch the download URLs in parallel, without conflicting with each other

Only display "Successfully uploaded" or "Upload failed" messages after the uploads have actually completed

Update imageAddressList only once, rather than asynchronously.

To be done:

Handle activity lifecycle changes

Tap into currentUploadTask and bind it to a view dialog/notification to show file upload progress

Update the UI once all the uploads are done

Updated code

Note: This was typed free-hand - expect a few typos.

upload.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        progressDialog.setMessage("Uploading .... ");
        progressDialog.show();
        upload.setClickable(false); // disable upload button whilst uploading

        final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("Pictures");
        final List<Uri> clonedImageList = new ArrayList<>(imageList);

        imageList.clear(); // empty old list?
        int imageListSize = clonedImageList.size();

        List<Task<Uri>> uploadedImageUrlTasks = new ArrayList<>(imageListSize);

        for (Uri imageUri : clonedImageList) {
            final String imageFilename = imageUri.getLastPathSegment();
            Log.d("upload.onClick()", "Starting upload for \"" + imageFilename + "\"...");

            StorageReference imageRef = storageReference.child(imageFilename); // Warning: potential for collisions/overwrite
            UploadTask currentUploadTask = imageRef.putFile(imageUri);

            Task<Uri> currentUrlTask = currentUploadTask
                .continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
                    @Override
                    public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
                        if (!task.isSuccessful()) {
                            Log.d("upload.onClick()", "Upload for \"" + imageFilename + "\" failed!");
                            throw task.getException(); // rethrow any errors
                        }

                        Log.d("upload.onClick()", "Upload for \"" + imageFilename + "\" finished. Fetching download URL...");
                        return imageRef.getDownloadUrl();
                    }
                })
                .continueWithTask(new Continuation<Uri, Uri>() { // purely for logging to debug, recommended to remove
                    @Override
                    public Task<Uri> then(@NonNull Task<Uri> task) throws Exception {
                        if (!task.isSuccessful()) {
                            Log.d("upload.onClick()", "Could not get download URL for \"" + imageFilename + "\"!");
                            throw task.getException(); // rethrow any errors
                        }

                        Log.d("upload.onClick()", "Download URL for \"" + imageFilename + "\" is \"" + task.getResult() + "\".");
                        return task.getResult();
                    }
                });

              uploadedImageUrlTasks.add(currentUrlTask);
        }

        // At this point, all the files are being uploaded in parallel
        // Each upload is tracked by the tasks in uploadedImageUrlTasks

        Tasks.whenAllComplete(uploadedImageUrlTasks)
            .addOnCompleteListener(new OnCompleteListener<List<Task<Uri>>>() {
                @Override
                public void onComplete(@NonNull List<Task<Uri>> tasks) {
                    int tasksCount = tasks.size();
                    List<Uri> failedUploads = new ArrayList<>();
                    imageAddressList.clear(); // empty old entries?

                    for (Task<Uri> task : tasks) {
                        if (task.isSuccessful()) {
                            successCount++;
                            Uri downloadUri = task.getResult();
                            imageAddressList.add(downloadUri.toString());
                        } else {
                            Uri imageUri = clonedImageList.get(tasks.indexOf(task));
                            failedUploads.add(imageUri);
                            Log.e("upload.onClick()", "Failed to upload/fetch URL for \"" + imageUri.getLastPathSegment() + "\" with exception", task.getException()); // log exception
                        }
                    }

                    progressDialog.dismiss(); // dismiss upload dialog

                    if (failedUploads.size() > 0) {
                        Toast.makeText(SignOutActivity.this, failedUploads.size() + "/" + tasksCount + " uploads failed.", Toast.LENGTH_LONG).show();
                        // TODO: Do something with list of failed uploads such as readd to the now empty upload list
                        imageList.addAll(failedUploads);
                        upload.setClickable(true);
                    } else {
                        Toast.makeText(SignOutActivity.this, "Successfully uploaded all " + tasksCount + " files.", Toast.LENGTH_LONG).show();
                    }

                    // TODO: Now that imageAddressList has been updated, update the UI - e.g tell recycler view to refresh
                }
            });
    }
});


来源: stackexchange

问:
Why Header component in NativeBase is not on top?
i got a little problem with Header component in NativeBase (UI Component for React Native). Its position should be on top. But, mine is below a white block. I don't know why its there.

Here my code

```<code>import React, { Component } from 'react';
import { Image } from 'react-native';
import {
  Container,
  Header,
  Left,
  Body,
  Right,
  Title,
  Content,
  Footer,
  FooterTab,
  Button,
  Icon,
  Text,
  List,
  ListItem,
  Switch,
  Item,
  Input,
  Form,
  DeckSwiper,
  Card,
  CardItem,
  Thumbnail,
  View
} from 'native-base';
import { Col, Row, Grid } from "react-native-easy-grid";
import { StackNavigator } from 'react-navigation';
import Expo from "expo";
import { cards, groups_category } from '../data/dummies';

class HomeScreen extends Component {

  constructor (props) {
    super(props);

    this.state = {
      loading: true,
      isUserLogin: false,
      searchStatus: false
    }

    this.showSearch = this.showSearch.bind(this);
    this.checkLoginStatus = this.checkLoginStatus.bind(this);
  }

  async componentWillMount() {
    await Expo.Font.loadAsync({
      'Roboto': require('native-base/Fonts/Roboto.ttf'),
      'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
      'Ionicons': require("@expo/vector-icons/fonts/Ionicons.ttf")
    });
    this.setState({ loading: false });
  }

  showSearch () {
    this.setState({ searchStatus: !this.state.searchStatus });
  }

  checkLoginStatus () {
    if (!this.state.isUserLogin) {
      return this.props.navigation.navigate('Login');
    } else {
      return
    }
  }

  render() {
    if (this.state.loading) {
      return <Expo.AppLoading />;
    }
    return (
      <Container>
        { this.state.searchStatus &&
          (<Header searchBar rounded>
            <Item regular>
              <Icon name='md-arrow-back' onPress={this.showSearch} />
              <Input placeholder='Contoh: Jakarta Memancing'/>
              <Icon name='search' />
            </Item>
          </Header>)
        }
        { !this.state.searchStatus &&
          (<Header>
            <Left>
              <Icon name='add' style={{color: '#FFFFFF'}} />
            </Left>
            <Body style={{ alignItems: 'center' }}>
              <Title>Komunitas</Title>
            </Body>
            <Right>
              <Icon name='search' style={{color: '#FFFFFF'}} onPress={this.showSearch} />
            </Right>
          </Header>)
        }
        {/* Content */}
        <Content padder={true}>
          <View style={{height: 470}}>
            <DeckSwiper
              dataSource={cards}
              renderItem={item =>
                <Card style={{ elevation: 3 }}>
                  <CardItem>
                    <Left>
                      <Thumbnail source={item.image} />
                      <Body>
                        <Text>{item.text}</Text>
                        <Text note>NativeBase</Text>
                      </Body>
                    </Left>
                  </CardItem>
                  <CardItem cardBody>
                    <Image style={{ height: 300, flex: 1 }} source={item.image} />
                  </CardItem>
                  <CardItem>
                    <Icon name="heart" style={{ color: '#ED4A6A' }} />
                    <Text>{item.name}</Text>
                  </CardItem>
                </Card>
              }
            />
          </View>
          <List>
            <ListItem itemHeader first>
              <Text>Kategori Grup</Text>
            </ListItem>
            {groups_category.map(group => {
                return (<ListItem key={group.id}>
                  <Left>
                    <Icon name={group.icon}/>
                  </Left>
                  <Body>
                    <Text>{group.name}</Text>
                  </Body>
                  <Right />
                </ListItem>)
              }
            )}
          </List>
        </Content>
        {/* Content */}
        <Footer>
          <FooterTab>
            <Button vertical active>
              <Icon active name="home" />
              <Text style={{fontSize: 9.5}}>Home</Text>
            </Button>
            <Button vertical>
              <Icon name="megaphone" />
              <Text style={{fontSize: 9.5}}>Baru</Text>
            </Button>
            <Button vertical>
              <Icon name="notifications" />
              <Text style={{fontSize: 9.5}}>Notifikasi</Text>
            </Button>
            <Button onPress={this.checkLoginStatus} vertical>
              <Icon name="person" />
              <Text style={{fontSize: 9.5}}>Profil</Text>
            </Button>
          </FooterTab>
        </Footer>
      </Container>
    );
  }
}

export default HomeScreen;
</code>```

It results like this

As you can see the Header which has search icon is located below an empty space / white color. Why this happen ? Maybe there are a lot of friends here had experienced it before when using NativeBase UI Component.

答:
UPDATE for React Navigation 5.x

If you want to use Nativebase's header with react navigation 5, you can do it like this:

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import {
  Header,
  Left,
  Body,
  Title,
  Button,
  Icon,
  View,
  Text
} from 'native-base';

const Stack = createStackNavigator();

const Home = () => {
    return (
        <View>
            <Text>Hello World</Text>
        </View>
    )
}

const CustomHeader = ({scene, previous, navigation}) => {
  const {options} = scene.descriptor;
  const title =
    options.headerTitle !== undefined
      ? options.headerTitle
      : options.title !== undefined
      ? options.title
      : scene.route.name;

  return (

      <Left>
        {previous ? (
          <Button transparent onPress={navigation.goBack}>
            <Icon name="arrow-back" />
          </Button>
        ) : (
          undefined
        )}
      </Left>

        <Title>{title}</Title>

  );
};

const App = () => {
    return (
        <NavigationContainer>
            <Stack.Navigator initialRouteName="Home">
                <Stack.Screen
                name="Home"
                component={Home}
                options={{
                header: (props) => <CustomHeader {...props} />,
              }}
                />
            </Stack.Navigator>
        </NavigationContainer>
    )
}
```

More of the options here https://reactnavigation.org/docs/en/stack-navigator.html

ContentLicense: CC BY-SA 3.0

Body:
i got a little problem with Header component in NativeBase (UI Component for React Native). Its position should be on top. But, mine is below a white block. I don't know why its there.

Here my code

import React, { Component } from 'react';
import { Image } from 'react-native';
import {
  Container,
  Header,
  Left,
  Body,
  Right,
  Title,
  Content,
  Footer,
  FooterTab,
  Button,
  Icon,
  Text,
  List,
  ListItem,
  Switch,
  Item,
  Input,
  Form,
  DeckSwiper,
  Card,
  CardItem,
  Thumbnail,
  View
} from 'native-base';
import { Col, Row, Grid } from "react-native-easy-grid";
import { StackNavigator } from 'react-navigation';
import Expo from "expo";
import { cards, groups_category } from '../data/dummies';

class HomeScreen extends Component {

  constructor (props) {
    super(props);

    this.state = {
      loading: true,
      isUserLogin: false,
      searchStatus: false
    }

    this.showSearch = this.showSearch.bind(this);
    this.checkLoginStatus = this.checkLoginStatus.bind(this);
  }

  async componentWillMount() {
    await Expo.Font.loadAsync({
      'Roboto': require('native-base/Fonts/Roboto.ttf'),
      'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
      'Ionicons': require("@expo/vector-icons/fonts/Ionicons.ttf")
    });
    this.setState({ loading: false });
  }

  showSearch () {
    this.setState({ searchStatus: !this.state.searchStatus });
  }

  checkLoginStatus () {
    if (!this.state.isUserLogin) {
      return this.props.navigation.navigate('Login');
    } else {
      return
    }
  }

  render() {
    if (this.state.loading) {
      return <Expo.AppLoading />;
    }
    return (
      <Container>
        { this.state.searchStatus &&
          (
            <Item regular>
              <Icon name='md-arrow-back' onPress={this.showSearch} />
              <Input placeholder='Contoh: Jakarta Memancing'/>
              <Icon name='search' />
            </Item>
          )
        }
        { !this.state.searchStatus &&
          (
            <Left>
              <Icon name='add' style={{color: '#FFFFFF'}} />
            </Left>

              <Title>Komunitas</Title>

            <Right>
              <Icon name='search' style={{color: '#FFFFFF'}} onPress={this.showSearch} />
            </Right>
          )
        }
        {/* Content */}
        <Content padder={true}>
          <View style={{height: 470}}>
            <DeckSwiper
              dataSource={cards}
              renderItem={item =>
                <Card style={{ elevation: 3 }}>
                  <CardItem>
                    <Left>
                      <Thumbnail source={item.image} />

                        <Text>{item.text}</Text>
                        <Text note>NativeBase</Text>

                    </Left>
                  </CardItem>
                  <CardItem cardBody>
                    <Image style={{ height: 300, flex: 1 }} source={item.image} />
                  </CardItem>
                  <CardItem>
                    <Icon name="heart" style={{ color: '#ED4A6A' }} />
                    <Text>{item.name}</Text>
                  </CardItem>
                </Card>
              }
            />
          </View>
          <List>
            <ListItem itemHeader first>
              <Text>Kategori Grup</Text>
            </ListItem>
            {groups_category.map(group => {
                return (<ListItem key={group.id}>
                  <Left>
                    <Icon name={group.icon}/>
                  </Left>

                    <Text>{group.name}</Text>

                  <Right />
                </ListItem>)
              }
            )}
          </List>
        </Content>
        {/* Content */}

          <FooterTab>
            <Button vertical active>
              <Icon active name="home" />
              <Text style={{fontSize: 9.5}}>Home</Text>
            </Button>
            <Button vertical>
              <Icon name="megaphone" />
              <Text style={{fontSize: 9.5}}>Baru</Text>
            </Button>
            <Button vertical>
              <Icon name="notifications" />
              <Text style={{fontSize: 9.5}}>Notifikasi</Text>
            </Button>
            <Button onPress={this.checkLoginStatus} vertical>
              <Icon name="person" />
              <Text style={{fontSize: 9.5}}>Profil</Text>
            </Button>
          </FooterTab>

      </Container>
    );
  }
}

export default HomeScreen;

It results like this

As you can see the Header which has search icon is located below an empty space / white color. Why this happen ? Maybe there are a lot of friends here had experienced it before when using NativeBase UI Component.

Body:
UPDATE for React Navigation 5.x

If you want to use Nativebase's header with react navigation 5, you can do it like this:

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

import {
  Header,
  Left,
  Body,
  Title,
  Button,
  Icon,
  View,
  Text
} from 'native-base';

const Stack = createStackNavigator();

const Home = () => {
    return (
        <View>
            <Text>Hello World</Text>
        </View>
    )
}

const CustomHeader = ({scene, previous, navigation}) => {
  const {options} = scene.descriptor;
  const title =
    options.headerTitle !== undefined
      ? options.headerTitle
      : options.title !== undefined
      ? options.title
      : scene.route.name;

  return (
    <Header>
      <Left>
        {previous ? (
          <Button transparent onPress={navigation.goBack}>
            <Icon name="arrow-back" />
          </Button>
        ) : (
          undefined
        )}
      </Left>
      <Body>
        <Title>{title}</Title>
      </Body>
    </Header>
  );
};

const App = () => {
    return (
        <NavigationContainer>
            <Stack.Navigator initialRouteName="Home">
                <Stack.Screen
                name="Home"
                component={Home}
                options={{
                header: (props) => <CustomHeader {...props} />,
              }}
                />
            </Stack.Navigator>
        </NavigationContainer>
    )
}

More of the options here https://reactnavigation.org/docs/en/stack-navigator.html

ContentLicense: CC BY-SA 4.0


问:
Most efficient way of converting a Data.ByteString.Lazy to a CStringLen
I need to encode some data to JSON and then push is to the syslog using hsyslog. The types of the two relevant functions are:

```<code>Aeson.encode :: a -> Data.ByteString.Lazy.ByteString

System.Posix.Syslog.syslog :: Maybe Facility
                           -> Priority
                           -> CStringLen
                           -> IO ()
</code>```

What's the most efficient way (speed & memory) to convert a Lazy.ByteString -> CStringLen? I found Data.ByteString.Unsafe, but it works only with ByteString, not Lazy.ByteString?

Shall I just stick a unsafeUseAsCStringLen . Data.String.Conv.toS and call it a day? Will it to the right thing wrt efficiency?

答:
I guess I would use Data.ByteString.Lazy.toStrict in place of toS, to avoid the additional package dependency.

Anyway, you won't find anything more efficient than:

```<code>unsafeUseAsCStringLen (toStrict lbs) $ \cstrlen -> ...
</code>```

In general, toStrict is an "expensive" operation, because a lazy ByteString will generally be made up of a bunch of "chunks" each consisting of a strict ByteString and not necessarily yet loaded into memory.  The toStrict function must force all the strict ByteString chunks into memory and ensure that they are copied into a single, contiguous block as required for a strict ByteString before the no-copy unsafeUseAsCStringLen is applied.

However, toStrict handles a lazy ByteString that consists of a single chunk optimally without any copying.

In practice, aeson uses an efficient Data.ByteString.Builder to create the JSON, and if the JSON is reasonably small (less than 4k, I think), it will build a single-chunk lazy ByteString.  In this case, toStrict is zero-copy, and unsafeUseAsCStringLen is zero copy, and the entire operation is basically free.

But note that, in your application, where you are passing the string to the syslogger, fretting about the efficiency of this operation is crazy.  My guess would be that you'd need thousands of copy operations to even make a dent in the performance of the overall action.

Body:
I need to encode some data to JSON and then push is to the syslog using hsyslog. The types of the two relevant functions are:

Aeson.encode :: a -> Data.ByteString.Lazy.ByteString

System.Posix.Syslog.syslog :: Maybe Facility
                           -> Priority
                           -> CStringLen
                           -> IO ()

What's the most efficient way (speed & memory) to convert a Lazy.ByteString -> CStringLen? I found Data.ByteString.Unsafe, but it works only with ByteString, not Lazy.ByteString?

Shall I just stick a unsafeUseAsCStringLen . Data.String.Conv.toS and call it a day? Will it to the right thing wrt efficiency?

Body:
I guess I would use Data.ByteString.Lazy.toStrict in place of toS, to avoid the additional package dependency.

Anyway, you won't find anything more efficient than:

unsafeUseAsCStringLen (toStrict lbs) $ \cstrlen -> ...

In general, toStrict is an "expensive" operation, because a lazy ByteString will generally be made up of a bunch of "chunks" each consisting of a strict ByteString and not necessarily yet loaded into memory.  The toStrict function must force all the strict ByteString chunks into memory and ensure that they are copied into a single, contiguous block as required for a strict ByteString before the no-copy unsafeUseAsCStringLen is applied.

However, toStrict handles a lazy ByteString that consists of a single chunk optimally without any copying.

In practice, aeson uses an efficient Data.ByteString.Builder to create the JSON, and if the JSON is reasonably small (less than 4k, I think), it will build a single-chunk lazy ByteString.  In this case, toStrict is zero-copy, and unsafeUseAsCStringLen is zero copy, and the entire operation is basically free.

But note that, in your application, where you are passing the string to the syslogger, fretting about the efficiency of this operation is crazy.  My guess would be that you'd need thousands of copy operations to even make a dent in the performance of the overall action.


问:
Retrieve Data from Isilon Server
I would like to retrieve folder info from Isilon server which is installed in my Local VM.

Below are the FolderInfo that i required to collect: CreateDate, AccessDate, ModifyDate, DirName,FileCount,Count,Size, FullAccessPath

using the link http://doc.isilon.com/onefs/7.0.2/help/en-us/

I see that i can get these information (CreateDate, AccessDate, ModifyDate, DirName,FileCount,Count,Size) from Extended property of the powershell. Can any one help me on retrieving the fullaccesspath of the folder or file.

答:
Please upgrade OneFS away from 7.0.2
You are programming against a very old (and obsolete) version.

I could not find information on "FullAccessPath" in MS docs ... can you provide example code with output pulling "FullAccessPath" from a local file/folder ?

If this "FullAccessPath" is dealing with ACLs ( like setfacl ) then you must connect to SMB share from Isilon which sets your account with "run as root" flag.

Title: Retrieve Data from Isilon Server


问:
Why are my links in html ul li not working?
I'm currently trying to build my first website (homework). For my dropdown menu, I used Dev Ed's tutorial for a dropdown menu, and it is working except that I can't click on the links in the dropdown bits.
(the mouse coursor still changes into that hand-symbol though)

How can I fix this?

nav {
  grid-column: 1/5;
  background: #2E3045;
  justify-content: center;
  border-radius: 10px;
}

nav a,
button {
  text-decoration: none;
  font-size: 1.7vw;
  font-family: Bahnschrift, sans-serif;
  color: #DFB830;
  font-weight: bold;
}

/* horizontal-menu */

.menu {
  height: auto;
  display: flex;
  justify-content: space-around;
  align-items: center;
}

/* styling horizontal-menu buttons */

.dropdown button,
.dd-buttons {
  background: none;
  border: none;
  cursor: pointer;
  text-transform: uppercase;
  padding-top: 1%;
  padding-bottom: 1%;
}

.menu button:hover,
.dd-buttons:hover {
  color: #ECEEFF;
}

/* styling the dropdown arrow */

@media only screen and (max-width: 480px) {
  .menu img {
    max-width: 7px;
    height: auto;
    display: inline-block;
  }
}

@media only screen and (min-width: 481px) {
  .menu img {
    max-width: 15px;
    height: auto;
    display: inline-block;
  }
}

/* dropdown list */

.dropdown {
  position: relative;
}

.dropdown ul {
  position: absolute;
  background: #DFB830;
  margin-top: 8px;
  min-width: 150%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-direction: column;
  list-style: none;
  border-radius: 5px;
  opacity: 0;
  pointer-events: none;
  transition: all 0.4s ease;
  transform: translateY(10px);
}

/* styling dropdown menu list items */

.dropdown li {
  width: 100%;
  height: 100%;
  line-height: 250%;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all 0.4s ease;
}

.dropdown a {
  font-size: 1.5vw;
  color: #2E3045;
}

/* when hovering over dropdown list */

.dropdown li:hover {
  background-color: #E9CF72;
}

.dropdown button:focus+ul {
  opacity: 1;
  pointer-events: all;
  transform: translateY(0px);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><!------------------------ menu ------------------------>
<nav>
  <div class="menu">
    <button class="dd-buttons">YouthDuo</button>
    <button class="dd-buttons">Galactic Spirit</button>
    <div class="dropdown">
      <button>Feng Shui <img src="images/dropdown icon.png"></button>
      <ul>
        <li>Feng Shui Basics</li>
        <li>CD's and DVD's</li>
        <li>Books and EBooks</li>
      </ul>
    </div>
    <div class="dropdown">
      <button>Color Alchemy <img src="images/dropdown icon.png"></button>
      <ul>
        <li>Living in Color</li>
        <li>Guided Training</li>
        <li>Jami Lin's Products</li>
      </ul>
    </div>
  </div>
</nav></code>```

答:
remove the pointer-events:none

```<code>.dropdown ul {
    position: absolute;
    background: #DFB830;
    margin-top: 8px;
    min-width: 150%;
    display: flex;
    justify-content: space-around;
    align-items: center;
    flex-direction: column;
    list-style: none;
    border-radius: 5px;
    opacity: 0;
    transition: all 0.4s ease;
    transform: translateY(10px);
}
</code>```

Body:
I'm currently trying to build my first website (homework). For my dropdown menu, I used Dev Ed's tutorial for a dropdown menu, and it is working except that I can't click on the links in the dropdown bits.
(the mouse coursor still changes into that hand-symbol though)

How can I fix this?

nav {
  grid-column: 1/5;
  background: #2E3045;
  justify-content: center;
  border-radius: 10px;
}

nav a,
button {
  text-decoration: none;
  font-size: 1.7vw;
  font-family: Bahnschrift, sans-serif;
  color: #DFB830;
  font-weight: bold;
}

/* horizontal-menu */

.menu {
  height: auto;
  display: flex;
  justify-content: space-around;
  align-items: center;
}

/* styling horizontal-menu buttons */

.dropdown button,
.dd-buttons {
  background: none;
  border: none;
  cursor: pointer;
  text-transform: uppercase;
  padding-top: 1%;
  padding-bottom: 1%;
}

.menu button:hover,
.dd-buttons:hover {
  color: #ECEEFF;
}

/* styling the dropdown arrow */

@media only screen and (max-width: 480px) {
  .menu img {
    max-width: 7px;
    height: auto;
    display: inline-block;
  }
}

@media only screen and (min-width: 481px) {
  .menu img {
    max-width: 15px;
    height: auto;
    display: inline-block;
  }
}

/* dropdown list */

.dropdown {
  position: relative;
}

.dropdown ul {
  position: absolute;
  background: #DFB830;
  margin-top: 8px;
  min-width: 150%;
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-direction: column;
  list-style: none;
  border-radius: 5px;
  opacity: 0;
  pointer-events: none;
  transition: all 0.4s ease;
  transform: translateY(10px);
}

/* styling dropdown menu list items */

.dropdown li {
  width: 100%;
  height: 100%;
  line-height: 250%;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all 0.4s ease;
}

.dropdown a {
  font-size: 1.5vw;
  color: #2E3045;
}

/* when hovering over dropdown list */

.dropdown li:hover {
  background-color: #E9CF72;
}

.dropdown button:focus+ul {
  opacity: 1;
  pointer-events: all;
  transform: translateY(0px);
}

    <button class="dd-buttons">YouthDuo</button>
    <button class="dd-buttons">Galactic Spirit</button>

      <button>Feng Shui </button>

Feng Shui Basics

CD's and DVD's

Books and EBooks

      <button>Color Alchemy </button>

Living in Color

Guided Training

Jami Lin's Products

Body:
remove the pointer-events:none

.dropdown ul {
    position: absolute;
    background: #DFB830;
    margin-top: 8px;
    min-width: 150%;
    display: flex;
    justify-content: space-around;
    align-items: center;
    flex-direction: column;
    list-style: none;
    border-radius: 5px;
    opacity: 0;
    transition: all 0.4s ease;
    transform: translateY(10px);
}


问:
Map count really counts or just checks existence
In CPP primer or other websites I have found the language of count (from map STL) definition very vague and misleading:

Searches the container for elements with a key equivalent to k and returns the number of matches

Now what I have studied so far is that key is singular and so is the mapped value - the mapped value can be changed through assignment.

So doesn't it just returns whether the container contains the key or not? Rather than the count? Where am I wrong in understanding the concept?

答:
According to cplusplus.com

Because all elements in a map container are unique, the function can only return 1 (if the element is found) or zero (otherwise).


问:
How to apply multiple transforms to the same element
I have an image of triangle which I use to create a mosaic of triangles.
This image is rotated with transform (rotate) and put in a grid layout.
I need to animate the rows of the layout to slide from different direction to their final position and i have used transform (translate).
My problem is that the animation start with the image in their original orientation and not with the rotated one.
How can I animate the rotated image?

See the allegated image.
https://gifyu.com/image/7lbW

EDIT
Here you can find my code, I'm sure there is a better way to do this, but right now I need this to work if possible.

#loader-container {
  width: 50vw;
  height: 12vw;
  max-width: 830px;
  position: relative;
  margin: auto;
}
.top-container {
  position: absolute;
  width: 20vw;
  height: 4vw;
  max-height: 100px;
  max-width: 500px;
  right: 10%;
  margin: 0.25vw;
}
.top {
  display: grid;
  grid-template-columns: repeat(15, 1fr);
  width: 100%;
  height: 100%;
}
.triangle {
  height: 100%;
  width: 100%;
  background-repeat: no-repeat;
  background-size: contain;
}
.blue {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/blue.gif");
}
.green {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/green.gif");
}
.grey {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/gray.gif");
}
.red {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/red.gif");
}
.yellow {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/yellow.gif");
}
.topright {
  transform: rotate(90deg);
}
.bottomleft {
  transform: rotate(270deg);
}
.bottomright {
  transform: rotate(180deg);
}
.column1 {
  grid-column: 1;
}
.column2 {
  grid-column: 2;
}
.column3 {
  grid-column: 3;
}
.column4 {
  grid-column: 4;
}
.column5 {
  grid-column: 5;
}
.column6 {
  grid-column: 6;
}
.column7 {
  grid-column: 7;
}
.column8 {
  grid-column: 8;
}
.column9 {
  grid-column: 9;
}
.column10 {
  grid-column: 10;
}
.column11 {
  grid-column: 11;
}
.column12 {
  grid-column: 12;
}
.column13 {
  grid-column: 13;
}
.column14 {
  grid-column: 14;
}
.column15 {
  grid-column: 15;
}
.top .row1 {
  grid-row: 1;
  animation: slideupdown 2s 0.2s backwards;
}
.top .row2 {
  grid-row: 2;
  animation: slideleftright 2s backwards;
}
.top .row3 {
  grid-row: 3;
  animation: sliderightleft 2s backwards;
}
@keyframes slideupdown {
  from {
    transform: translateY(-176px);
    opacity: 0;
  }
  to {
    transform: translateY(0%);
    opacity: 1;
  }
}
@keyframes slidedownup {
  from {
    transform: translateY(176px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
@keyframes slideleftright {
  from {
    transform: translateX(850px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes sliderightleft {
  from {
    transform: translateX(-850px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="top-container">
      <div class="top">
         <div class="triangle topleft green tt01 column1 row3"></div>
         <div class="triangle topright blue tt02 column2 row1"></div>
         <div class="triangle bottomleft yellow column3 row1"></div>
         <div class="triangle bottomright blue column3 row3"></div>
         <div class="triangle topleft red column4 row2"></div>
         <div class="triangle bottomleft grey column4 row3"></div>
         <div class="triangle bottomleft green column5 row1"></div>
         <div class="triangle topleft yellow column6 row2"></div>
         <div class="triangle bottomleft red column6 row3"></div>
         <div class="triangle topleft green column7 row2"></div>
         <div class="triangle bottomright grey column7 row2"></div>
         <div class="triangle topleft blue column7 row3"></div>
         <div class="triangle topright blue column8 row1"></div>
         <div class="triangle topleft yellow column8 row2"></div>
         <div class="triangle bottomright grey column8 row2"></div>
         <div class="triangle topright grey column8 row3"></div>
         <div class="triangle bottomleft red column8 row3"></div>
         <div class="triangle bottomleft yellow column9 row1"></div>
         <div class="triangle topleft red column9 row2"></div>
         <div class="triangle bottomright blue column9 row2"></div>
         <div class="triangle topleft green column9 row3"></div>
         <div class="triangle bottomright green column9 row3"></div>
         <div class="triangle topleft yellow column10 row1"></div>
         <div class="triangle bottomright red column10 row1"></div>
         <div class="triangle topleft green column10 row2"></div>
         <div class="triangle bottomright grey column10 row2"></div>
         <div class="triangle bottomleft blue column10 row3"></div>
         <div class="triangle bottomleft yellow column11 row1"></div>
         <div class="triangle topleft yellow column11 row2"></div>
         <div class="triangle bottomright grey column11 row2"></div>
         <div class="triangle topleft red column11 row3"></div>
         <div class="triangle bottomright grey column11 row3"></div>
         <div class="triangle bottomleft green column12 row1"></div>
         <div class="triangle bottomleft blue column12 row2"></div>
         <div class="triangle topleft green column12 row3"></div>
         <div class="triangle bottomright grey column12 row3"></div>
         <div class="triangle bottomleft grey column13 row3"></div>
         <div class="triangle bottomright blue column14 row3"></div>
         <div class="triangle bottomleft red column15 row3"></div>
      </div>
   </div></code>```

https://codepen.io/RiccioBastardo/pen/mdJPVyg

答:
Without seeing your code it is hard to answer. BUT I think the reason this is happening is because transform is being overwritten in the animation.

Here is simple working example:

```

<pre class="lang-css prettyprint-override"><code>.triangle {
  border: 20px transparent solid;
  border-right-color: red;
  display: inline-block;
  animation-name: example;
  animation-duration: 1s;
  transform: rotate(45deg);
  animation-fill-mode: forwards;

}

@keyframes example {
  from {
    transform: translate(0px, 0px) rotate(45deg);
  }
  to {
    transform: translate(1000px, 0px) rotate(45deg);
  }
}
</code>```

[EDIT] Here are my suggestions after the author shared the code.

Basically, you are declaring transform more than once for a given element. in CSS the last occurrence overrides all previous occurrences. In order to solve this, you need to work around this. There is four ways you can do this:

Convert

```

<p>to something like </p>

<pre class="lang-html prettyprint-override"><code><div class="triangle-holder topleft column7 row2">
    <div class="triangle green"></div>
</div>
</code>```

This allows you to have two different transforms on two different elements without overriding each other (as what's happening in the original code) The transform: rotate() is applied to .triangle, while transform: translate() is applied to .triangle-holder

Get rid of  transform: rotate() completely (as well as the background image), by using borders (see above for an example). This will only work for 90 degree rotations

Get rid of transform: translate() and use margin or top/left for positioning.

Animate each triangle explicitly in order to combine your transforms into one transformation.

I would recommend the second option, as it requires minimal changes to your code, and AFAIK is browser compatible way of creating CSS triangles.

Body:
I have an image of triangle which I use to create a mosaic of triangles.
This image is rotated with transform (rotate) and put in a grid layout.
I need to animate the rows of the layout to slide from different direction to their final position and i have used transform (translate).
My problem is that the animation start with the image in their original orientation and not with the rotated one.
How can I animate the rotated image?

See the allegated image.
https://gifyu.com/image/7lbW

EDIT
Here you can find my code, I'm sure there is a better way to do this, but right now I need this to work if possible.

#loader-container {
  width: 50vw;
  height: 12vw;
  max-width: 830px;
  position: relative;
  margin: auto;
}
.top-container {
  position: absolute;
  width: 20vw;
  height: 4vw;
  max-height: 100px;
  max-width: 500px;
  right: 10%;
  margin: 0.25vw;
}
.top {
  display: grid;
  grid-template-columns: repeat(15, 1fr);
  width: 100%;
  height: 100%;
}
.triangle {
  height: 100%;
  width: 100%;
  background-repeat: no-repeat;
  background-size: contain;
}
.blue {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/blue.gif");
}
.green {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/green.gif");
}
.grey {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/gray.gif");
}
.red {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/red.gif");
}
.yellow {
  background-image: url("https://www.hiboucoop-staging.org/wbo/wp-content/uploads/2020/02/yellow.gif");
}
.topright {
  transform: rotate(90deg);
}
.bottomleft {
  transform: rotate(270deg);
}
.bottomright {
  transform: rotate(180deg);
}
.column1 {
  grid-column: 1;
}
.column2 {
  grid-column: 2;
}
.column3 {
  grid-column: 3;
}
.column4 {
  grid-column: 4;
}
.column5 {
  grid-column: 5;
}
.column6 {
  grid-column: 6;
}
.column7 {
  grid-column: 7;
}
.column8 {
  grid-column: 8;
}
.column9 {
  grid-column: 9;
}
.column10 {
  grid-column: 10;
}
.column11 {
  grid-column: 11;
}
.column12 {
  grid-column: 12;
}
.column13 {
  grid-column: 13;
}
.column14 {
  grid-column: 14;
}
.column15 {
  grid-column: 15;
}
.top .row1 {
  grid-row: 1;
  animation: slideupdown 2s 0.2s backwards;
}
.top .row2 {
  grid-row: 2;
  animation: slideleftright 2s backwards;
}
.top .row3 {
  grid-row: 3;
  animation: sliderightleft 2s backwards;
}
@keyframes slideupdown {
  from {
    transform: translateY(-176px);
    opacity: 0;
  }
  to {
    transform: translateY(0%);
    opacity: 1;
  }
}
@keyframes slidedownup {
  from {
    transform: translateY(176px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}
@keyframes slideleftright {
  from {
    transform: translateX(850px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
@keyframes sliderightleft {
  from {
    transform: translateX(-850px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

https://codepen.io/RiccioBastardo/pen/mdJPVyg

Body:
Without seeing your code it is hard to answer. BUT I think the reason this is happening is because transform is being overwritten in the animation.

Here is simple working example:

<div class="triangle"></div>

.triangle {
  border: 20px transparent solid;
  border-right-color: red;
  display: inline-block;
  animation-name: example;
  animation-duration: 1s;
  transform: rotate(45deg);
  animation-fill-mode: forwards;

}

@keyframes example {
  from {
    transform: translate(0px, 0px) rotate(45deg);
  }
  to {
    transform: translate(1000px, 0px) rotate(45deg);
  }
}

[EDIT] Here are my suggestions after the author shared the code.

Basically, you are declaring transform more than once for a given element. in CSS the last occurrence overrides all previous occurrences. In order to solve this, you need to work around this. There is four ways you can do this:

Convert

<div class="triangle topleft green column7 row2"></div>

to something like

<div class="triangle-holder topleft column7 row2">
    <div class="triangle green"></div>
</div>

This allows you to have two different transforms on two different elements without overriding each other (as what's happening in the original code) The transform: rotate() is applied to .triangle, while transform: translate() is applied to .triangle-holder

Get rid of  transform: rotate() completely (as well as the background image), by using borders (see above for an example). This will only work for 90 degree rotations

Get rid of transform: translate() and use margin or top/left for positioning.

Animate each triangle explicitly in order to combine your transforms into one transformation.

I would recommend the second option, as it requires minimal changes to your code, and AFAIK is browser compatible way of creating CSS triangles.


问:
Create a distinct List<String>
I have three lists of List<String> type, named as list1, list2, and list3.

I add some items into list1 then copy them to a new list which is list2. Then I create the list3 to add some more items then copy them again to list2. However, I need list2 to contain distinct items, so how would I exclude the duplicate items and avoid adding them into list2?

This is what I have tried out:

List<String> list2 = new ArrayList<>();
List<String> list1 = new ArrayList<>();

                list1.add("String1");
                list1.add("String2");

                list2.addAll(list1);

List<String> list3 = new ArrayList<>();

list3.add("String1");
list3.add("String3");

list2.addAll(list3);
```

答:
Depends on the amount of "effort" you want to put into it and the size of the lists (and hence the performance).

You could simply iterate over the elements of list3:

```<code>list3.forEach(s ->
{
    if (list2.contains(s))
    {
        list2.remove(s);
    }
    else
    {
        list2.add(s);
    }
});
</code>```

Title: Create a distinct List<String>

Body:
Depends on the amount of "effort" you want to put into it and the size of the lists (and hence the performance).

You could simply iterate over the elements of list3:

list3.forEach(s ->
{
    if (list2.contains(s))
    {
        list2.remove(s);
    }
    else
    {
        list2.add(s);
    }
});


问:
Row Values in GRID field for a Submitted Form

we can only seem to get the column value for each row but not the row value.

So, in the grid field example we get an array as follows
(element 1) = OPPORTUNITY: OT Not Considered;
(element 2) = OPPORTUNITY: OT Considered

Is there a way we can also get the Row values?

Option 1 a second parallel array
(element 1) = OT 1;
(element 2) = OT 2

or Option 2
(element 1) = OT 1&&OPPORTUNITY: OT Not Considered;
(element 2) = OT 2&&OPPORTUNITY: OT Considered

Here's the GAS we're currently using to get the Form Submission

function onFormSubmit(e) {
 var data = {
      "id": e.source.getId(),
   "OTC_user" : Session.getActiveUser().getEmail(),
      "title": e.source.getTitle() ? e.source.getTitle() : "Untitled Form",
      "is_private": e.source.requiresLogin(),
      "is_published": e.source.isAcceptingResponses(),
      "id": e.response.getId(),
      "timestamp": e.response.getTimestamp(),
      "fields": e.response.getItemResponses().map(function(y) {
    return {
        h: y.getItem().getTitle(),
        k: y.getResponse()
    }
      }, this).reduce(function(r, y) {
    r[y.h] = y.k;
    return r
      }, {})
 };

 var options = {
  method: "post",
  payload: JSON.stringify(data, null, 2),
  contentType: "application/json; charset=utf-8",
 };

 UrlFetchApp.fetch("https://<WEBHOOK URL REMOVED", options);
};
```

答:
Rows and columns of CheckboxGridItem cab be accessed.

For CheckboxGridItem questions, this returns a String[][] array in which the answers at row index n corresponds to the question at row n + 1 in the checkbox grid. If a respondent did not answer a question in the grid, that answer is returned as ''. (GAS Class ItemResponse)

This example is an edited example from GAS Class FormResponse:

```<code>function doSomething() {

var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
  for (var i = 0; i < formResponses.length; i++) {
    var formResponse = formResponses[i];
    var itemResponses = formResponse.getItemResponses();
    for (var j = 0; j < itemResponses.length; j++) {
      var itemResponse = itemResponses[j];
      Logger.log('Response #%s to the question (horizontal) "%s" was (vertical) "%s"',
          (i + 1).toString(),
          itemResponse.getItem().asCheckboxGridItem().getColumns(),
          itemResponse.getItem().asCheckboxGridItem().getRows());
    }
  }
/*
[20-02-15 17:30:18:028 CET] Response #1 to the question (horizontal) "[ja, neen,
misschien]" was (vertical) "[aap, noot, mies]"
*/
}
</code>```

Body:
Rows and columns of CheckboxGridItem cab be accessed.

For CheckboxGridItem questions, this returns a String[][] array in which the answers at row index n corresponds to the question at row n + 1 in the checkbox grid. If a respondent did not answer a question in the grid, that answer is returned as ''. (GAS Class ItemResponse)

This example is an edited example from GAS Class FormResponse:

function doSomething() {

var form = FormApp.getActiveForm();
var formResponses = form.getResponses();
  for (var i = 0; i < formResponses.length; i++) {
    var formResponse = formResponses[i];
    var itemResponses = formResponse.getItemResponses();
    for (var j = 0; j < itemResponses.length; j++) {
      var itemResponse = itemResponses[j];
      Logger.log('Response #%s to the question (horizontal) "%s" was (vertical) "%s"',
          (i + 1).toString(),
          itemResponse.getItem().asCheckboxGridItem().getColumns(),
          itemResponse.getItem().asCheckboxGridItem().getRows());
    }
  }
/*
[20-02-15 17:30:18:028 CET] Response #1 to the question (horizontal) "[ja, neen,
misschien]" was (vertical) "[aap, noot, mies]"
*/
}


问:
I need to access a Tuple in Python
I was using get request to get some data by this code

```<code>at = airtable.Airtable('BASE_ID', 'API_KEY')
airtable_data = at.get('Table 3')
print(airtable_data)
</code>```

and the results was

```<code>OrderedDict([('records', [OrderedDict([('id', 'rec3qP7SjyowO'), ('fields',OrderedDict([('User', 'User'), ('Text', 'TEST'), ('Date', '2020-01-15T13:09:03.000Z')])), ('createdTime', '2020-01-15T13:09:09.000Z')]), OrderedDict([('id', 'recOUVoNXHak'), ('fields', OrderedDict([('User', 'user'), ('Text', 'TEST'), ('Date', '2020-01-15T13:05:43.000Z')])), ('createdTime', '2020-01-15T13:08:55.000Z')])])])
</code>```

then I used

```<code>airtable_list = (list(airtable_data))
print(airtable_list[0])
</code>```

the results was
records
only and I can't find a way to extract the rest of the data

答:
since your variable airtable_data is OrderedDict type you can get the rest of the data by accessing the value for the key records:

```<code>my_data = airtable_data['records']
</code>```

Title: I need to access a Tuple in Python

Body:
I was using get request to get some data by this code

at = airtable.Airtable('BASE_ID', 'API_KEY')
airtable_data = at.get('Table 3')
print(airtable_data)

and the results was

OrderedDict([('records', [OrderedDict([('id', 'rec3qP7SjyowO'), ('fields',OrderedDict([('User', 'User'), ('Text', 'TEST'), ('Date', '2020-01-15T13:09:03.000Z')])), ('createdTime', '2020-01-15T13:09:09.000Z')]), OrderedDict([('id', 'recOUVoNXHak'), ('fields', OrderedDict([('User', 'user'), ('Text', 'TEST'), ('Date', '2020-01-15T13:05:43.000Z')])), ('createdTime', '2020-01-15T13:08:55.000Z')])])])

then I used

airtable_list = (list(airtable_data))
print(airtable_list[0])

the results was
records
only and I can't find a way to extract the rest of the data

Body:
since your variable airtable_data is OrderedDict type you can get the rest of the data by accessing the value for the key records:

my_data = airtable_data['records']


问:
Save and Load Random Number Generator State in C++11
This question has been asked before (stackoverflow) but the (accepted) answer is not satisfactory.

The following example saves and loads the state but depending on the number of generated values it works or it doesn't:

```<code>#include <fstream>
#include <iostream>
#include <random>
#include <cassert>

int main()
{
  const int preN = 4;
  const int middleN = 0;

  // initialize randGen
  std::mt19937 randGen1;
  std::normal_distribution<double> distribution1;

  // print some initial random numbers
  for (int i=0;i<preN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // save state
  std::cout << std::endl << "Saving...\n";
  {
    std::ofstream fout("seed.dat");
    fout << randGen1;
  }

  // maybe advance randGen1
  for (int i=0;i<middleN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // load saved state into randGen2
  std::cout << std::endl << "Loading...\n";
  std::ifstream fin("seed.dat");
  std::mt19937 randGen2;
  fin >> randGen2;
  std::normal_distribution<double> distribution2;

  // are both randGen equal?
  assert(randGen1 == randGen2);

  // print numbers from both generators
  std::cout << "Generator1\tGenerator2\n";
  std::cout << distribution1(randGen1) << "\t"
            << distribution2(randGen2) << "\n";

  return 0;

}
</code>```

With these parameters it works like expected. However, if I set preN=3 the output looks like:

```<code>0.13453 -0.146382 0.46065
Saving...

Loading...
Generator1  Generator2
-1.87138    0.163712
</code>```

Why did the assert not apply? Now I set preN=3 and middleN=1 and the output is

```<code>0.13453 -0.146382 0.46065
Saving...
-1.87138
Loading...
Generator1  Generator2
0.163712    0.163712
</code>```

If I set middleN to anything larger than 1 the assert applies.
Can anyone explain what is going on? What am I doing wrong or not understanding?

Tested with GCC5.4.0 and CLANG3.8.0 on Linux

答:
Here is how one can save and restore seed forrandom numbers of double float precision. It should be similar for integers - use jrand48 instead of erand48.

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

int main(int argc, char **argv)
{

     unsigned short savedseed[3];
     unsigned short currentseed[3];
     double x;

     /*-- initialize ramdom seed to whatever --*/
     currentseed[0]= 23;
     currentseed[1]= 45;
     currentseed[2]= 67;

     printf("\n");

     /*-- generate three random numbers  --*/
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     printf("\n");

     /*-- save seed  --*/
     memcpy(savedseed, currentseed, 3*sizeof(unsigned short));

     /*-- generate next three random numbers  --*/
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     printf("\n", x);

     /*-- restore seed  --*/
     memcpy(currentseed, savedseed,  3*sizeof(unsigned short));

     /*-- generate the same three random numbers again --*/
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     x =  erand48(currentseed);     printf("%g\n", x);
     printf("\n");
}
```

Body:
This question has been asked before (stackoverflow) but the (accepted) answer is not satisfactory.

The following example saves and loads the state but depending on the number of generated values it works or it doesn't:

#include <fstream>
#include <iostream>
#include <random>
#include <cassert>

int main()
{
  const int preN = 4;
  const int middleN = 0;

  // initialize randGen
  std::mt19937 randGen1;
  std::normal_distribution<double> distribution1;

  // print some initial random numbers
  for (int i=0;i<preN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // save state
  std::cout << std::endl << "Saving...\n";
  {
    std::ofstream fout("seed.dat");
    fout << randGen1;
  }

  // maybe advance randGen1
  for (int i=0;i<middleN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // load saved state into randGen2
  std::cout << std::endl << "Loading...\n";
  std::ifstream fin("seed.dat");
  std::mt19937 randGen2;
  fin >> randGen2;
  std::normal_distribution<double> distribution2;

  // are both randGen equal?
  assert(randGen1 == randGen2);

  // print numbers from both generators
  std::cout << "Generator1\tGenerator2\n";
  std::cout << distribution1(randGen1) << "\t"
            << distribution2(randGen2) << "\n";

  return 0;

}

With these parameters it works like expected. However, if I set preN=3 the output looks like:

0.13453 -0.146382 0.46065
Saving...

Loading...
Generator1  Generator2
-1.87138    0.163712

Why did the assert not apply? Now I set preN=3 and middleN=1 and the output is

0.13453 -0.146382 0.46065
Saving...
-1.87138
Loading...
Generator1  Generator2
0.163712    0.163712

If I set middleN to anything larger than 1 the assert applies.
Can anyone explain what is going on? What am I doing wrong or not understanding?

Tested with GCC5.4.0 and CLANG3.8.0 on Linux


问:
How to pull out strings from array on iPhone?
I want to pull out a string from an array by index.

e.g array with object: @"Hello", @"World"

How to get @"World" from it? I use array[1], but it seems not work.

答:
You could also use an enumerator, like this:</p>

```<code>NSEnumerator* enumerator = [myArray objectEnumerator];
ArrayObject* myObject;

while (myObject = [enumerator nextObject])
    {
// do something with myObject
}
</code>```

OwnerDisplayName: iphony

ContentLicense: CC BY-SA 2.5

Body:
You could also use an enumerator, like this:

NSEnumerator* enumerator = [myArray objectEnumerator];
ArrayObject* myObject;

while (myObject = [enumerator nextObject])
    {
// do something with myObject
}

OwnerDisplayName: Jane Sales


问:
How to update file in GIT using APIs - gives error 404 error
I am trying to update file in GIT using API and getting error code 404.

```<code>updateServersonGIT(servList: string): Observable<Array<any>> {
    return this.http.put<Array<any>>("https://api.github.com/repos/amshreyas/servers/contents/serv.json",{"Authorization" : "token <my token>",servList}).pipe(catchError(this.handleError));
  }
</code>```

I have generated oAuth token.
Please advise.

答:
It may be failing because you haven't specified the required fields in the docs to go with the PUT: https://developer.github.com/v3/repos/contents/#create-or-update-a-file

In particular you need to ensure that these fields are provided:

message - the commit message to associate with the change

committer - a JSON object containing the committer name and email

content a base64-encoded string of the new file contents

Here's an example from the docs:

```<code>{
  "message": "my commit message",
  "committer": {
    "name": "Monalisa Octocat",
    "email": "octocat@github.com"
  },
  "content": "bXkgbmV3IGZpbGUgY29udGVudHM="
}
</code>```

It's not clear to me whether this is occurring, as the sample doesn't provide enough information to run locally for someone else.

It also might be failing if your token doesn't have public_repo set.

Body:
I am trying to update file in GIT using API and getting error code 404.

updateServersonGIT(servList: string): Observable<Array<any>> {
    return this.http.put<Array<any>>("https://api.github.com/repos/amshreyas/servers/contents/serv.json",{"Authorization" : "token <my token>",servList}).pipe(catchError(this.handleError));
  }

I have generated oAuth token.
Please advise.

Body:
It may be failing because you haven't specified the required fields in the docs to go with the PUT: https://developer.github.com/v3/repos/contents/#create-or-update-a-file

In particular you need to ensure that these fields are provided:

message - the commit message to associate with the change

committer - a JSON object containing the committer name and email

content a base64-encoded string of the new file contents

Here's an example from the docs:

{
  "message": "my commit message",
  "committer": {
    "name": "Monalisa Octocat",
    "email": "octocat@github.com"
  },
  "content": "bXkgbmV3IGZpbGUgY29udGVudHM="
}

It's not clear to me whether this is occurring, as the sample doesn't provide enough information to run locally for someone else.

It also might be failing if your token doesn't have public_repo set.


问:
VBA MS-WORD Trouble with sendkeys
I'm having some issue with this code

```<code>Private Sub CortarSobrantes()
'Procedimiento que llama al comando "Comprimir imágenes" con parámetros
    With Application.CommandBars.FindControl(ID:=6382)
        SendKeys "%T%n%C{ENTER}", False ' Las letras equivalen a los accesos de teclado en la ventana, ~ para ejecucion
        .Execute
    End With
End Sub
</code>```

If I hit Run (F5) inside the project, it runs OK, but when I try to call it from a button shortcut it doesn't catch the SendKeys. This also happens if I try to run it step by step (F8)

BTW %T%n%C is for Spanish command combination (all images, not compress, without resolution change and deleting cropped areas)

The reason I'm using SendKeys is that I'm trying to remove cropped areas within a function in order to call it from a button, so I could skip marking the options. As far as I know, there's nothing in the object model that allows this.

Am I missing something with the focus?

答:
I'm also having trouble with the SendKeys-statement.

I'm trying to send Alt= to a Word document. Thereby changing some mahematical formula in an equation field. For instance: ((x_1 q+x_2 p)/(p+q),(y_1 q+y_2 p)/(p+q))

After some time I found that the SendKeys-statement works as advertised only and ONLY if there's no further statement in my macro.

I know this is a bit awkward, but there it is.

Consider the following:

```<code>Public Sub test()

    Dim test As String
    test = ActiveWindow.Selection.Text

    SendKeys "%=", True

'    MsgBox test

End Sub
</code>```

This works fine.

Copy/paste the formula above in a Word-document, open VBA in Word, make a new Module and copy/paste the Sub above into it.

Select the formula.

You must start the Sub form the Macro's menu (Alt+F8).

You'll notice that the formula will change in an equation-field and gets centered in the middle.

Run the macro again and the formula is changed back in standard text-format.
Now activate the MsgBox-statement and you'll notice that the SendKeys-statement doesn't work anymore.

I know this is hardly a workaround for the problem, but maybe someone will find this information useful!

Title: VBA MS-WORD Trouble with sendkeys

Body:
I'm having some issue with this code

Private Sub CortarSobrantes()
'Procedimiento que llama al comando "Comprimir imágenes" con parámetros
    With Application.CommandBars.FindControl(ID:=6382)
        SendKeys "%T%n%C{ENTER}", False ' Las letras equivalen a los accesos de teclado en la ventana, ~ para ejecucion
        .Execute
    End With
End Sub

If I hit Run (F5) inside the project, it runs OK, but when I try to call it from a button shortcut it doesn't catch the SendKeys. This also happens if I try to run it step by step (F8)

BTW %T%n%C is for Spanish command combination (all images, not compress, without resolution change and deleting cropped areas)

The reason I'm using SendKeys is that I'm trying to remove cropped areas within a function in order to call it from a button, so I could skip marking the options. As far as I know, there's nothing in the object model that allows this.

Am I missing something with the focus?

Body:
I'm also having trouble with the SendKeys-statement.

I'm trying to send Alt= to a Word document. Thereby changing some mahematical formula in an equation field. For instance: ((x_1 q+x_2 p)/(p+q),(y_1 q+y_2 p)/(p+q))

After some time I found that the SendKeys-statement works as advertised only and ONLY if there's no further statement in my macro.

I know this is a bit awkward, but there it is.

Consider the following:

Public Sub test()

    Dim test As String
    test = ActiveWindow.Selection.Text

    SendKeys "%=", True

'    MsgBox test

End Sub

This works fine.

Copy/paste the formula above in a Word-document, open VBA in Word, make a new Module and copy/paste the Sub above into it.

Select the formula.

You must start the Sub form the Macro's menu (Alt+F8).

You'll notice that the formula will change in an equation-field and gets centered in the middle.

Run the macro again and the formula is changed back in standard text-format.
Now activate the MsgBox-statement and you'll notice that the SendKeys-statement doesn't work anymore.

I know this is hardly a workaround for the problem, but maybe someone will find this information useful!


问:
How to give each cell random digit number
I want to give each cell a random double-digit number between 50-500
i'm trying to use math.floor(math.random() as function but no success so far

also how I can target only one cell, for example i have 5x5 slots 5 rows 5 col, and I want to target the top left cell in the corner alone, and instead of random generated numbers like the rest cells, i want to give it a symbol where i can control it, so if the symbol is in top left corner, i click on middle for example and it moves there, replacing the generated number which was in the middle and keeping the top left right corner empty

sorry for the trouble, any help really appreciated

```<code><html>
<head>
<style>
td{
border:2px solid black;
width:10px;
height:10px;
}
td:hover{background-color:lightgreen;}
.grn{
background-color:green;
color:white;
}
</style>

<body>
<div id='ff'></div>

<script>
var isCol=0;
var board=[];
for(r=0;r<7;r++){
    var line=[];
    for(c=0;c<7;c++){
        line.push(r);
    }
    board.push(line);
}

function prs(c,r){
    showTable(c,r);
    isCol=(isCol+1)%2;
}

function toColor(col,row,chosen_col,chosen_row){
var ret=false;
switch(isCol){
    case 0:
        if(row==chosen_row){
            ret=true;
        }
        break;
    case 1:
        if(col==chosen_col){
            ret=true;
        }
        break;
}

return ret;
}

function showTable(chosen_col,chosen_row){
var str="";
str+="<table border=1>";
for(row=0;row<7;row++){
    str+="<tr>";
    for(col=0;col<7;col++){
        str+="<td onclick='prs("+col+","+row+")'";
        if(toColor(col,row,chosen_col,chosen_row)){
            str+=" class='grn' ";
        }
        str+=">";
str+=board[row][col];
        str+="</td>";
    }
    str+="</tr>";
}
str+="</table>";

 document.getElementById("ff").innerHTML=str;
}

showTable(-1);
</script>
</body>
</html>

</code>```

答:
You can try with this.

function randRange(min, max) {
  return Math.floor(Math.random() * (max - min) + min);
}

const rows = 7;
const cols = 7;

const slots = Array.from(new Array(rows), () =>
  new Array(cols).fill(0).map(() => randRange(50, 500))
);

console.log(slots);```


答:
you must use the pattern Iterator to remove an element in a list, this will work fine for you:</p>

```<code>    Iterator<String> iter = list2.iterator();
    String value = "String1";
    while(iter.hasNext()) {
        if(iter.next().equals(value)) {
            iter.remove();
        }
    }
</code>```

Title: Create a distinct List<String>

Body:
I have three lists of List<String> type, named as list1, list2, and list3.

I add some items into list1 then copy them to a new list which is list2. Then I create the list3 to add some more items then copy them again to list2. However, I need list2 to contain distinct items, so how would I exclude the duplicate items and avoid adding them into list2?

This is what I have tried out:

List<String> list2 = new ArrayList<>();
List<String> list1 = new ArrayList<>();

                list1.add("String1");
                list1.add("String2");

                list2.addAll(list1);

List<String> list3 = new ArrayList<>();

list3.add("String1");
list3.add("String3");

list2.addAll(list3);

Body:
you must use the pattern Iterator to remove an element in a list, this will work fine for you:

    Iterator<String> iter = list2.iterator();
    String value = "String1";
    while(iter.hasNext()) {
        if(iter.next().equals(value)) {
            iter.remove();
        }
    }


问:
Using PHP to check for mysql DB changes
I'm creating a new web application and I only want to update certain tables when the db is changed, this will be done by firing off a PHP script in a JavaScript setInterval.

My issue is that I am having a hard time trying to find a way to easily determine if certain rows in the database table have changed. In other instances I have used "show table status" and compared that against the last update_time that I had already stored.

In this case though, I don't want to look at the entire table, I just need to know if the rows in my query have changed. I originally tried to md5 the array, as well as md5 on the serialization of the array. It seems that neither of them work and return the same md5 hash each time.

Just for example, here is my query:

```<code>$getUserTable = mysql_query("select * from uct_admin.resources where teamID='62' order by ResourceName");
</code>```

Solution that I came up with after reading the answers:

```<code>$getUserTable = mysql_query("select * from uct_admin.resources where teamID='62' order by csiname");
while ($row = mysql_fetch_assoc($getUserTable)) {
    $arrayTest[] = $row;
}
$hash = md5(http_build_query($arrayTest, 'flags_'));
</code>```

This works perfectly due to the nested array returned from the query.

答:
I would consider adding an additional TIMESTAMP field to the table that's updated on UPDATE/INSERT then you could just check SELECT MAX(lastModified) WHERE teamID=62

If you don't want to change the table structure you could add a trigger to this table and have it keep track of the last change to each teams's data in a separate table.

Title: Using PHP to check for mysql DB changes

Body:
I'm creating a new web application and I only want to update certain tables when the db is changed, this will be done by firing off a PHP script in a JavaScript setInterval.

My issue is that I am having a hard time trying to find a way to easily determine if certain rows in the database table have changed. In other instances I have used "show table status" and compared that against the last update_time that I had already stored.

In this case though, I don't want to look at the entire table, I just need to know if the rows in my query have changed. I originally tried to md5 the array, as well as md5 on the serialization of the array. It seems that neither of them work and return the same md5 hash each time.

Just for example, here is my query:

$getUserTable = mysql_query("select * from uct_admin.resources where teamID='62' order by ResourceName");

Solution that I came up with after reading the answers:

$getUserTable = mysql_query("select * from uct_admin.resources where teamID='62' order by csiname");
while ($row = mysql_fetch_assoc($getUserTable)) {
    $arrayTest[] = $row;
}
$hash = md5(http_build_query($arrayTest, 'flags_'));

This works perfectly due to the nested array returned from the query.


问:
Use "arp -a" to retreive MAC address of corresponding IP Adress
I was trying to convert the MAC address of my phone to it's IP address.

```<code>var arpStream = ExecuteCommandLine("arp", "-a");
List<string> result = new List<string>();
   while (!arpStream.EndOfStream)
  {
      var line = arpStream.ReadLine().Trim();
      result.Add(line);
  }
</code>```

Using the above code, I store it in a list in the following form:

```<code>  192.168.137.1         2e-bb-58-0a-2f-34     dynamic
  192.168.137.44        a8-3e-0e-61-3f-db     dynamic
  192.168.137.91        d4-63-c6-b2-ac-38     dynamic
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.252           01-00-5e-00-00-fc     static
</code>```

What I can't figure out is, how to retrieve a specific IP for the given MAC.
Assume that my phone is the device with the physical address: a8-3e-0e-61-3f-db, how can I store it's IP as a string somewhere?

答:
You can use a Dictionary  data structure in C# to hold key-value pair information in your case it is Ipaddress-Macaddress information

Usage

```<code>var macofIpaddress = dict["192.168.137.1"];
</code>```

Code

```<code>string output = "";
var proc = new ProcessStartInfo("cmd.exe", "/c arp -a")
{
      CreateNoWindow = true,
      UseShellExecute = false,
      RedirectStandardOutput = true,
      RedirectStandardError = true,
      WorkingDirectory = @"C:\Windows\System32\"
};
Process p = Process.Start(proc);
p.OutputDataReceived += (sender, args1) => { output += args1.Data + Environment.NewLine; };
p.BeginOutputReadLine();
p.WaitForExit();

var dict = new Dictionary<string, string>();
var lines = output.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach(var line in lines)
{
      if (line.Contains("static") || line.Contains("dynamic"))
      {
         var elements = line.Split(new string[] { "    " }, StringSplitOptions.RemoveEmptyEntries);
        var ipAdd =   elements[0].Trim();
        var macAdd = elements[1].Trim();
        dict.Add(ipAdd,macAdd);
      }

}

</code>```

Output:

Body:
I was trying to convert the MAC address of my phone to it's IP address.

var arpStream = ExecuteCommandLine("arp", "-a");
List<string> result = new List<string>();
   while (!arpStream.EndOfStream)
  {
      var line = arpStream.ReadLine().Trim();
      result.Add(line);
  }

Using the above code, I store it in a list in the following form:

  192.168.137.1         2e-bb-58-0a-2f-34     dynamic
  192.168.137.44        a8-3e-0e-61-3f-db     dynamic
  192.168.137.91        d4-63-c6-b2-ac-38     dynamic
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.252           01-00-5e-00-00-fc     static

What I can't figure out is, how to retrieve a specific IP for the given MAC.
Assume that my phone is the device with the physical address: a8-3e-0e-61-3f-db, how can I store it's IP as a string somewhere?

Body:
You can use a Dictionary  data structure in C# to hold key-value pair information in your case it is Ipaddress-Macaddress information

Usage

var macofIpaddress = dict["192.168.137.1"];

Code

string output = "";
var proc = new ProcessStartInfo("cmd.exe", "/c arp -a")
{
      CreateNoWindow = true,
      UseShellExecute = false,
      RedirectStandardOutput = true,
      RedirectStandardError = true,
      WorkingDirectory = @"C:\Windows\System32\"
};
Process p = Process.Start(proc);
p.OutputDataReceived += (sender, args1) => { output += args1.Data + Environment.NewLine; };
p.BeginOutputReadLine();
p.WaitForExit();

var dict = new Dictionary<string, string>();
var lines = output.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

foreach(var line in lines)
{
      if (line.Contains("static") || line.Contains("dynamic"))
      {
         var elements = line.Split(new string[] { "    " }, StringSplitOptions.RemoveEmptyEntries);
        var ipAdd =   elements[0].Trim();
        var macAdd = elements[1].Trim();
        dict.Add(ipAdd,macAdd);
      }

}

Output:


问:
Recaptcha Missing input response using Angularjs and PHP
I am having trouble with recaptcha requests. I am using the vc Recaptcha service for Angular JS with PHP validation. I receive the error 'missing-input-reponse' from the reCaptcha object when submitting the form.

The site is built with AngularJS and PHP, I am using a data factory to send requests to the server using the $http object. I am implementing password reset functionality and I want to use reCaptcha on the reset form. This is where I'm having trouble.

The backend is all working properly, it definitely seems to be a problem with the Captcha request. My reCaptcha API codes are working elsewhere on the site but without the AngularJS implementation.

My controller looks like this:

```<code>MySite.controller('passwordResetController', function($rootScope, $scope, $window, $location, $routeParams, Data, vcRecaptchaService) {
    $rootScope.showControls = false;
    $scope.response = null;
    $scope.widgetId = null;
    $scope.form = {email: '', id: '', response: ''};
    $scope.model = {
        key: // MY SITE KEY //
    };
    $scope.setResponse = function (response) {
        console.info('Response available');
        $scope.response = response;
    };
    $scope.setWidgetId = function (widgetId) {
        console.info('Created widget ID: %s', widgetId);
        $scope.widgetId = widgetId;
    };
    $scope.cbExpiration = function() {
        console.info('Captcha expired. Resetting response object');
        vcRecaptchaService.reload($scope.widgetId);
        $scope.response = null;
     };
    $scope.sendReset = function(form) {
        var valid;
        $scope.form.response = $scope.response;
        console.log($scope.form.response);
        Data.post('/sendreset', {form:form})
        .then(function(results) {
            console.log(results);
            if (results.status === 'success') {
                valid = true;
            } else {
                valid = false;
            }
            Data.toast(results);
        });
        console.log('sending the captcha response to the server', $scope.response);
        if (valid) {
            console.log('Success');
            Data.post('/createRequest', {
                form: form
            }).then(function(results) {
                if (results.status === 'success') {
                    $scope.sendMail(form);
                }
            });
        } else {
            console.log('Failed validation');
            vcRecaptchaService.reload($scope.widgetId);
        }
    }
    $scope.sendMail = function(form) {
        Data.post('/sendPasswordReset', {
            form: form
        }).then(function(results) {
            Data.toast(results);
            if (results.status === 'success') {
                $location.path('login');
            }
        });
    }
});
</code>```

My PHP validation is:

```<code>$app->post('/sendreset', function() use ($app) {
    $r = json_decode($app->request->getBody());
    $post = [
        'secret' => //== MY SECRET KEY ==//,
        'response' => $r->form->response
    ];
    $ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $response = curl_exec($ch);
    curl_close($ch);
    var_dump($response);
    $response = json_decode($response, true);
    // check result
    if (isset($response['success']) && $response['success'] == true) {
        $response['status'] = 'success';
        echoResponse(200, $response);
    } else {
        $response['status'] = 'error';
        $response['message'] = 'Captcha test failed';
        echoResponse(201, $response);
    }
});
</code>```

The Data functionality is all working properly.
Any help would be hugely appreciated.

答: The response from the server is a string not an array. I changed the controller to search for 'true' in the string, works fine now.</p>

Body:
I am having trouble with recaptcha requests. I am using the vc Recaptcha service for Angular JS with PHP validation. I receive the error 'missing-input-reponse' from the reCaptcha object when submitting the form.

The site is built with AngularJS and PHP, I am using a data factory to send requests to the server using the $http object. I am implementing password reset functionality and I want to use reCaptcha on the reset form. This is where I'm having trouble.

The backend is all working properly, it definitely seems to be a problem with the Captcha request. My reCaptcha API codes are working elsewhere on the site but without the AngularJS implementation.

My controller looks like this:

MySite.controller('passwordResetController', function($rootScope, $scope, $window, $location, $routeParams, Data, vcRecaptchaService) {
    $rootScope.showControls = false;
    $scope.response = null;
    $scope.widgetId = null;
    $scope.form = {email: '', id: '', response: ''};
    $scope.model = {
        key: // MY SITE KEY //
    };
    $scope.setResponse = function (response) {
        console.info('Response available');
        $scope.response = response;
    };
    $scope.setWidgetId = function (widgetId) {
        console.info('Created widget ID: %s', widgetId);
        $scope.widgetId = widgetId;
    };
    $scope.cbExpiration = function() {
        console.info('Captcha expired. Resetting response object');
        vcRecaptchaService.reload($scope.widgetId);
        $scope.response = null;
     };
    $scope.sendReset = function(form) {
        var valid;
        $scope.form.response = $scope.response;
        console.log($scope.form.response);
        Data.post('/sendreset', {form:form})
        .then(function(results) {
            console.log(results);
            if (results.status === 'success') {
                valid = true;
            } else {
                valid = false;
            }
            Data.toast(results);
        });
        console.log('sending the captcha response to the server', $scope.response);
        if (valid) {
            console.log('Success');
            Data.post('/createRequest', {
                form: form
            }).then(function(results) {
                if (results.status === 'success') {
                    $scope.sendMail(form);
                }
            });
        } else {
            console.log('Failed validation');
            vcRecaptchaService.reload($scope.widgetId);
        }
    }
    $scope.sendMail = function(form) {
        Data.post('/sendPasswordReset', {
            form: form
        }).then(function(results) {
            Data.toast(results);
            if (results.status === 'success') {
                $location.path('login');
            }
        });
    }
});

My PHP validation is:

$app->post('/sendreset', function() use ($app) {
    $r = json_decode($app->request->getBody());
    $post = [
        'secret' => //== MY SECRET KEY ==//,
        'response' => $r->form->response
    ];
    $ch = curl_init('https://www.google.com/recaptcha/api/siteverify');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    $response = curl_exec($ch);
    curl_close($ch);
    var_dump($response);
    $response = json_decode($response, true);
    // check result
    if (isset($response['success']) && $response['success'] == true) {
        $response['status'] = 'success';
        echoResponse(200, $response);
    } else {
        $response['status'] = 'error';
        $response['message'] = 'Captcha test failed';
        echoResponse(201, $response);
    }
});

The Data functionality is all working properly.
Any help would be hugely appreciated.