问:
SwiftUI send action from a page to the PageViewController
I have set up a PageViewController in SwiftUI, following the known Tutorial Interfacing with UIKit, with UIViewControllerRepresentable etc.

My array of controllers consists of simple SwiftUI views. I pass a simple IntroPage struct to supply the content. The views are nested, as is good SwiftUI practice, thus:

```<code>PageView
-   IntroScreen                // part of the pages array
    -   VStack
        -   Text
        -   Image
        -   ButtonView         // a separate view struct
            - HStack
                - ForEach      // iterating through the buttons in my IntroPage Object
                    - Button
PageControl
</code>```

Now I want to include some buttons on these views. They should be configurable via my IntroPage struct. One of them advances to the next page in the PageViewController, another tells the PageViewController to add more pages first, another button dismisses the entire PageViewController.

I cannot figure out, how get access to these methods in the PageViewController, where to implement them (the instance view? the coordinator of the PageViewController?) and how to reach the objects I need (e.g. the currentPage Binding variable of the PageViewController).

For example, I have implemented a forward() function in the PageViewController's coordinator:

```<code>func forward() {
   if parent.currentPage < parent.controllers.count - 1 {
       parent.currentPage += 1
   }
}
</code>```

...which works fine, with animations and all, if I add a button right beside the PageView on my final View. But I still cannot call this from the button contained in the child view.

Any ideas?

EDIT: Upon request, here is a situation in the ButtonView.

struct IntroButtonView: View {
    var page: IntroPage
    var body: some View {
        HStack() {
           Button(action:dismiss) {
              Text("LocalizedButtonTitle")
           }
           // ... more buttons, based on certain conditions
        }
    }

    func dismiss() {
         // how to dismiss the modally presented controller ?
    }

    func next()    {
         // how to advance to the next page
    }

    func expand()  {
         // how to add more pages to the pages array
    }
}
```

Or maybe I am completely wrong and still think in terms of "events" rather than "declaration"...

答:
OK, I figured it out. Not intuitive at first, I have to say. Coming from traditional event based programming, it's quite a different way of thinking

I used a @State variable in the main instance of the view.

I used @Binding variables to deal with the state both upstream (ViewControllers, Controls) and downstream (subviews). So, for example, I used a variable to tell the dataSource of the UIPageViewController if or not to return a view controller before/after the current one.

For the dismissing the modally presented controller I used

```<code>@Environment(\.presentationMode) var presentationMode

...

func dismiss() {
  self.presentationMode.wrapptedValue.dismiss()
}
</code>```

Similarly,

```<code>...
@Binding var currentPage: int
...

Button(action: next) { Text("Next Page") }
...

...
func next() {
    currentPage += 1
}
</code>```

There were a few caveats in deciding how to nest the views and what variables to pick for the bindings, but it is clear to me now. The biggest problem was ultimately where the "source of truth" should be anchored. It turned out, right in the "middle", i.e. below the controller and above the particular views.

Hope this is useful for others looking for something similar.

Body:
I have set up a PageViewController in SwiftUI, following the known Tutorial Interfacing with UIKit, with UIViewControllerRepresentable etc.

My array of controllers consists of simple SwiftUI views. I pass a simple IntroPage struct to supply the content. The views are nested, as is good SwiftUI practice, thus:

PageView
-   IntroScreen                // part of the pages array
    -   VStack
        -   Text
        -   Image
        -   ButtonView         // a separate view struct
            - HStack
                - ForEach      // iterating through the buttons in my IntroPage Object
                    - Button
PageControl

Now I want to include some buttons on these views. They should be configurable via my IntroPage struct. One of them advances to the next page in the PageViewController, another tells the PageViewController to add more pages first, another button dismisses the entire PageViewController.

I cannot figure out, how get access to these methods in the PageViewController, where to implement them (the instance view? the coordinator of the PageViewController?) and how to reach the objects I need (e.g. the currentPage Binding variable of the PageViewController).

For example, I have implemented a forward() function in the PageViewController's coordinator:

func forward() {
   if parent.currentPage < parent.controllers.count - 1 {
       parent.currentPage += 1
   }
}

...which works fine, with animations and all, if I add a button right beside the PageView on my final View. But I still cannot call this from the button contained in the child view.

Any ideas?

EDIT: Upon request, here is a situation in the ButtonView.

struct IntroButtonView: View {
    var page: IntroPage
    var body: some View {
        HStack() {
           Button(action:dismiss) {
              Text("LocalizedButtonTitle")
           }
           // ... more buttons, based on certain conditions
        }
    }

    func dismiss() {
         // how to dismiss the modally presented controller ?
    }

    func next()    {
         // how to advance to the next page
    }

    func expand()  {
         // how to add more pages to the pages array
    }
}

Or maybe I am completely wrong and still think in terms of "events" rather than "declaration"...

Body:
OK, I figured it out. Not intuitive at first, I have to say. Coming from traditional event based programming, it's quite a different way of thinking

I used a @State variable in the main instance of the view.

I used @Binding variables to deal with the state both upstream (ViewControllers, Controls) and downstream (subviews). So, for example, I used a variable to tell the dataSource of the UIPageViewController if or not to return a view controller before/after the current one.

For the dismissing the modally presented controller I used

@Environment(\.presentationMode) var presentationMode

...

func dismiss() {
  self.presentationMode.wrapptedValue.dismiss()
}

Similarly,

...
@Binding var currentPage: int
...

Button(action: next) { Text("Next Page") }
...

...
func next() {
    currentPage += 1
}

There were a few caveats in deciding how to nest the views and what variables to pick for the bindings, but it is clear to me now. The biggest problem was ultimately where the "source of truth" should be anchored. It turned out, right in the "middle", i.e. below the controller and above the particular views.

Hope this is useful for others looking for something similar.


来源: stackexchange

问:
html radio button has to be selected by default on page load
I am trying to do make the radio button selected by default on page load.

From the below screen it is a frame which is loaded. I am trying to make the radio buttons enable by using

document.formName.radioButtonId[1].checked = true;

Where formName is my form name that I declared in html, radioButtonId is id for radio button I used in html.

```<code><div>
 <form name = "formName">
.
.
.
.
   <div>
     <input type = "radio"
            id = "radioButton"
.
.
.
   </div>
 </form>
</div>

</code>```

So my expectation is from the above code Joe radio button has to be enabled.

But the html is not completely loaded and when I do
document.formName.radioButtonId[1].checked = true; the error on console says radioButton was undefined because of the form is not available.

I am not able to access any of the elements from form until it is completely loaded. Is there any way that I can check for the page title is loaded or visible then do the condition that I want to do?

I tried

```<code>if (document.readyState === "complete") { //do something }
</code>```

This didn't work because document.readyState is always complete as the document is referring to parent document from the screenshot you can see it was referring to background page.

Once the Modify Name is completely loaded then I was able to access formName form and I was able to make Joe as selected using document.formName.radioButtonId[1].checked = true;

I am making Joe as checked based on condition from the code that I have (fyi). That might change so want to be generic.

[![Modify Name is child to background image like a popup][2]][2]
Need help on how to make Joe as checked after loading the page automatically.

答:
```<code><input type = "radio" id = "radioButton" checked>
</code>```

OR in Javascript

```<code>window.onload = function() {..}

</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am trying to do make the radio button selected by default on page load.

From the below screen it is a frame which is loaded. I am trying to make the radio buttons enable by using

document.formName.radioButtonId[1].checked = true;

Where formName is my form name that I declared in html, radioButtonId is id for radio button I used in html.

 <form name = "formName">
.
.
.
.

     <input type = "radio"
            id = "radioButton"
.
.
.

 </form>

So my expectation is from the above code Joe radio button has to be enabled.

But the html is not completely loaded and when I do
document.formName.radioButtonId[1].checked = true; the error on console says radioButton was undefined because of the form is not available.

I am not able to access any of the elements from form until it is completely loaded. Is there any way that I can check for the page title is loaded or visible then do the condition that I want to do?

I tried

if (document.readyState === "complete") { //do something }

This didn't work because document.readyState is always complete as the document is referring to parent document from the screenshot you can see it was referring to background page.

Once the Modify Name is completely loaded then I was able to access formName form and I was able to make Joe as selected using document.formName.radioButtonId[1].checked = true;

I am making Joe as checked based on condition from the code that I have (fyi). That might change so want to be generic.

[![Modify Name is child to background image like a popup][2]][2]
Need help on how to make Joe as checked after loading the page automatically.

Body:
<input type = "radio" id = "radioButton" checked>

OR in Javascript

window.onload = function() {..}


问:
CloudFormation: WAF Association always fails with Internal Failure
I am trying to associate Web ACL to API gateway. I am using WAFv2. The snippet of my code is as below-

```<code>WAFAssociation:
    Type: 'AWS::WAFv2::WebACLAssociation'
    Properties:
      WebACLArn:
      - Fn::ImportValue:
            !Sub "${AWS::Region}-${AWS::AccountId}-APIGateway-WebACL"
      ResourceArn: !Sub
        - "arn:${AWS::Partition}:apigateway:{AWS::Region}::/restapis/{api}/stages/{stageName}"
        - api: !Ref RestApi
</code>```

I have referred https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wafv2-webaclassociation.html for this and written it. I am trying to deploy this resource in a stack, but this resource deployment always getting failed with error "Internal Failure". I am not able to find the rootcause of the issue.

答:
The ResourceArn is incorrect. Its missing $ in few places. Please have a look at the following form:

```<code>  ResourceArn: !Sub
    - "arn:${AWS::Partition}:apigateway:${AWS::Region}::/restapis/${api}/stages/${stageName}"
    - api: !Ref RestApi
</code>```

Also, please check examples from docs:

```<code>Name: !Sub
  - www.${Domain}
  - { Domain: !Ref RootDomainName }
</code>```

In addition please make sure that all the external components are correct, such as stageName and RestApi.

Body:
I am trying to associate Web ACL to API gateway. I am using WAFv2. The snippet of my code is as below-

WAFAssociation:
    Type: 'AWS::WAFv2::WebACLAssociation'
    Properties:
      WebACLArn:
      - Fn::ImportValue:
            !Sub "${AWS::Region}-${AWS::AccountId}-APIGateway-WebACL"
      ResourceArn: !Sub
        - "arn:${AWS::Partition}:apigateway:{AWS::Region}::/restapis/{api}/stages/{stageName}"
        - api: !Ref RestApi

I have referred https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wafv2-webaclassociation.html for this and written it. I am trying to deploy this resource in a stack, but this resource deployment always getting failed with error "Internal Failure". I am not able to find the rootcause of the issue.

Body:
The ResourceArn is incorrect. Its missing $ in few places. Please have a look at the following form:

  ResourceArn: !Sub
    - "arn:${AWS::Partition}:apigateway:${AWS::Region}::/restapis/${api}/stages/${stageName}"
    - api: !Ref RestApi

Also, please check examples from docs:

Name: !Sub
  - www.${Domain}
  - { Domain: !Ref RootDomainName }

In addition please make sure that all the external components are correct, such as stageName and RestApi.


问:
How to fake image upload for testing with Intervention image package using Laravel
I have a test asserting that images can be uploaded. Here is the code...

```<code>// Test

$file = UploadedFile::fake()->image('image_one.jpg');
Storage::fake('public');

$response = $this->post('/api/images', [
'images' => $file
]);
</code>```

Then in controller i am doing something simpler..

```<code>$file->store('images', 'public');
</code>```

And asserting couple of things. and it works like charm.

But now i need to resize the image using Intervention image package. for that i have a following code:

```<code> Image::make($file)
        ->resize(1200, null)
        ->save(storage_path('app/public/images/' . $file->hashName()));
</code>```

And in case if directory does not existing i am checking first this and creating one -

```<code>if (!Storage::exists('app/public/images/')) {
        Storage::makeDirectory('public/images/', 666, true, true);
         }
</code>```

Now Test should be green and i will but the issue is that every time i run tests it upload a file into storage directory. Which i don't want. I just need to fake the uploading and not real one.

Any Solution ?

Thanks in advance :)

答:
You need to store your file using the Storage facade. Storage::putAs does not work because it does not accept intervention image class. However you can you use Storage::put:

```<code>$file = UploadedFile::fake()->image('image_one.jpg');
Storage::fake('public');

// Somewhere in your controller
$image = Image::make($file)
        ->resize(1200, null)
        ->encode('jpg', 80);

Storage::disk('public')->put('images/' . $file->hashName(), $image);

// back in your test
Storage::disk('public')->assertExists('images/' . $file->hashName());
</code>```

Body:
I have a test asserting that images can be uploaded. Here is the code...

// Test

$file = UploadedFile::fake()->image('image_one.jpg');
Storage::fake('public');

$response = $this->post('/api/images', [
'images' => $file
]);

Then in controller i am doing something simpler..

$file->store('images', 'public');

And asserting couple of things. and it works like charm.

But now i need to resize the image using Intervention image package. for that i have a following code:

 Image::make($file)
        ->resize(1200, null)
        ->save(storage_path('app/public/images/' . $file->hashName()));

And in case if directory does not existing i am checking first this and creating one -

if (!Storage::exists('app/public/images/')) {
        Storage::makeDirectory('public/images/', 666, true, true);
         }

Now Test should be green and i will but the issue is that every time i run tests it upload a file into storage directory. Which i don't want. I just need to fake the uploading and not real one.

Any Solution ?

Thanks in advance :)

Body:
You need to store your file using the Storage facade. Storage::putAs does not work because it does not accept intervention image class. However you can you use Storage::put:

$file = UploadedFile::fake()->image('image_one.jpg');
Storage::fake('public');

// Somewhere in your controller
$image = Image::make($file)
        ->resize(1200, null)
        ->encode('jpg', 80);

Storage::disk('public')->put('images/' . $file->hashName(), $image);

// back in your test
Storage::disk('public')->assertExists('images/' . $file->hashName());


问:
What is the authorization URL if authorizing against a sandbox environment?
I guess this is a 2-part question.

I am using Postman to test the connected app I set up in a Salesforce sandbox environment. Should I be sending the request to https://login.salesforce.com/services/oauth2/token or https://xxx--partial.lightning.force.com/services/oauth2/token", which is our sandbox?

When I send the request to https://login.salesforce.com/services/oauth2/token I receive an "Invalid_grant" error with a description of "authentication failure". If I change the url to "https://xxx--partial.lightning.force.com/services/oauth2/token", which is our sandbox, I get an "invalid_request" error with a description of "must use HTTP POST". Here is the url with parameters: https://xxx--partial.lightning.force.com/services/oauth2/token?grant_type=password&client_id=clientIdHere &client_secret=clientSecretHere&username=myEmailAddress&password=myPassword&Content-Type=application/x-www-form-urlencoded

Any help is greatly appreciated.

Also posted here : https://salesforce.stackexchange.com/questions/307644/what-is-the-authorization-url-if-authorizing-against-a-sandbox-environment

答:
If you’re verifying authentication on a sandbox organization, use “test.salesforce.com” instead of “login.salesforce.com” in all the OAuth endpoints listed above.</p>

```<code>https://test.salesforce.com/services/oauth2/token
</code>```

Body:
If you’re verifying authentication on a sandbox organization, use “test.salesforce.com” instead of “login.salesforce.com” in all the OAuth endpoints listed above.

https://test.salesforce.com/services/oauth2/token


问:
Memory Leak in C#
Is it ever possible in a managed system to leak memory when you make sure that all handles, things that implement IDispose are disposed?

Would there be cases where some variables are left out?

答:
The only leaks (other than bugs in the runtime which may be present, though not terribly likely due to garbage collection) are going to be for native resources.  If you P/Invoke into a native library which opens file handles, or socket connections, or whatever on your managed application's behalf, and you never explicitly close them (and don't handle them in a disposer or destructor/finalizer), you can have memory or resource leaks because the runtime cannot manage all of those automatically for you.

If you stick with purely managed resources, though, you should be just fine.  If you experience any form of memory leak without calling into native code, then that's a bug.

OwnerDisplayName: Joan Venge

ContentLicense: CC BY-SA 2.5

Title: Memory Leak in C#

LastEditorDisplayName: strager

OwnerDisplayName: Michael Trausch


问:
Can a List.Sort using a randomized Comparison delegate run infinitely?
I'm investigating and performance testing various ways of randomizing ordered collections, and I was looking at the option of passing a Comparison delegate that just randomly returns the comparison result. For example:

```<code>int RandomComparison<T> (T x, T y)
{
    return this.random.Next (-1, 2);
}
</code>```

However, as I do not know the sorting algorithm used under the hood, I do not know if this could possibly lead to the sort logic never completing. While this method seems generally unreliable performance-wise, I'm wondering if it is actually dangerously unusable?

答: Once you've passed a sort routine a function that does not give a consistent order, there is no guarantee what will happen.  One would hope that C# does nothing bad, but I know from experience that C++ has a disturbing tendency to dump core in that situation.</p>

ContentLicense: CC BY-SA 3.0

Body:
I'm investigating and performance testing various ways of randomizing ordered collections, and I was looking at the option of passing a Comparison delegate that just randomly returns the comparison result. For example:

int RandomComparison<T> (T x, T y)
{
    return this.random.Next (-1, 2);
}

However, as I do not know the sorting algorithm used under the hood, I do not know if this could possibly lead to the sort logic never completing. While this method seems generally unreliable performance-wise, I'm wondering if it is actually dangerously unusable?


问:
epoll_wait() in a thread after close()
I have a main thread and a worker thread. The worker thread's code looks like something like this:

```<code>thread = ::std::thread([this]() {
    struct epoll_event events[50];

    for (;;)
    {
      if (int const n =
        epoll_wait(efd, events, 50, -1))
      {
      //...
</code>```

I was hoping that a close(efd) in the main thread would cause the worker thread's epoll_wait() call to return, but it doesn't happen. What can I do to exit from the worker thread's infinite loop?

答:
So, I answer my own question after a long time. Just as I noted in my comments, it's also possible to send a signal to the thread containing the epoll_wait().

```<code>bool terminate_meh{};

extern "C"
{

static void sig_handler(int) noexcept
{
  terminate_meh = true;
}

}

{
  struct sigaction act{};

  act.sa_handler = sig_handler;
  sigemptyset(&act.sa_mask);

  sigaction(SIGUSR2, &act, {});
}
</code>```

When you want to kill the waiting thread:

```<code>pthread_kill(thread.native_handle(), SIGUSR2);
</code>```

any blocking function (epoll_wait()) will be interrupted and terminate_meh will be set.

Title: epoll_wait() in a thread after close()

Body:
I have a main thread and a worker thread. The worker thread's code looks like something like this:

thread = ::std::thread([this]() {
    struct epoll_event events[50];

    for (;;)
    {
      if (int const n =
        epoll_wait(efd, events, 50, -1))
      {
      //...

I was hoping that a close(efd) in the main thread would cause the worker thread's epoll_wait() call to return, but it doesn't happen. What can I do to exit from the worker thread's infinite loop?

Body:
So, I answer my own question after a long time. Just as I noted in my comments, it's also possible to send a signal to the thread containing the epoll_wait().

bool terminate_meh{};

extern "C"
{

static void sig_handler(int) noexcept
{
  terminate_meh = true;
}

}

{
  struct sigaction act{};

  act.sa_handler = sig_handler;
  sigemptyset(&act.sa_mask);

  sigaction(SIGUSR2, &act, {});
}

When you want to kill the waiting thread:

pthread_kill(thread.native_handle(), SIGUSR2);

any blocking function (epoll_wait()) will be interrupted and terminate_meh will be set.


问:
Calling a function inside a const with props in react js
I have a dashboard and I have a function in it, this is a modal type and it holds a form. When the form is completed, the data entered appears on the table at the bottom of my dashboard.

Presently, the data in the table is loaded quite alright but whenever I click on the button ( that brings up the form, when I type init the form dissapear..basically the form disappears on click.

Here is my code below... thanks

import React, {useState,useContext,useEffect} from 'react';
import TransactionItem from '../components/TransactionItem';
import TransactionService from '../Services/TransactionService';
import Message from '../components/Message';
import { AuthContext } from '../Context/AuthContext';
import { Line, Pie } from "react-chartjs-2";
import {
  Card,
  CardHeader,
  CardBody,
  CardFooter,
  CardTitle,
  Table,
  Row,
  Col,
  Button,
  FormGroup,
  Input,
  Modal
} from "reactstrap";

const Dashboard = props => {
  const [transaction,setTransaction] = useState({amount : "", date : "", token : "", meter : "", transactionid : ""});
    const [transactions,setTransactions] = useState([]);
    const [message,setMessage] = useState(null);
    const authContext = useContext(AuthContext);

    useEffect(()=>{
      TransactionService.getTransactions().then(data =>{
          setTransactions(data.transactions);
      });
  },[]);

  function Recharge() {

  const [transactionModal, setTransactionModal] = useState(false);

  const onSubmit = e =>{
    e.preventDefault();
    TransactionService.postTransaction(transaction).then(data =>{
        const { message } = data;
        resetForm();
        if(!message.msgError){
            TransactionService.getTransactions().then(getData =>{
                setTransactions(getData.transactions);
                setMessage(message);
            });
        }
        else if(message.msgBody === "UnAuthorized"){
            setMessage(message);
            authContext.setUser({username : "", role : ""});
            authContext.setIsAuthenticated(false);
        }
        else{
            setMessage(message);
        }
    });
}

const onChange = e =>{
  setTransaction({...transaction,[e.target.name] : e.target.value});

}

const resetForm = ()=>{
  setTransaction({amount : "", date : "", token : "", meter : "", transactionid : ""});
}

return (

  <>
  <Button
    className="btn-round"
    color="success"
    type="button"
    onClick={() => setTransactionModal(true)}
  >Recharge
  </Button>
  <Modal
    isOpen={transactionModal}
    toggle={() => setTransactionModal(false)}
    modalClassName="modal-register"
  >

      <button
        aria-label="Close"
        className="close"
        data-dismiss="modal"
        type="button"
        onClick={() => setTransactionModal(false)}
      >
        ×
      </button>

Enter Details

      <form onSubmit={onSubmit}>
      <FormGroup>
        Amount
        <Input
          defaultValue=""
          placeholder="Enter date"
          name="amount"
          value={transaction.amount}
          onChange={onChange}
          type="text" />
      </FormGroup>
      <FormGroup>
        Date
        <Input
          defaultValue=""
          name="date"
          value={transaction.date}
          onChange={onChange}
          placeholder="Enter date"
          type="text" />
      </FormGroup>
      <FormGroup>
        Token
        <Input
          defaultValue=""
          name="token"
          value={transaction.token}
          onChange={onChange}
          placeholder="Enter token"
          type="text" />
      </FormGroup>
      <FormGroup>
        Meter
        <Input
          defaultValue=""
          name="meter"
          value={transaction.meter}
          onChange={onChange}
          className="form-control"
          placeholder="Enter meter"
          type="text" />
      </FormGroup>
      <FormGroup>
        ID
        <Input
          defaultValue=""
          placeholder="Enter Id"
          name="transactionid"
          value={transaction.transactionid}
          onChange={onChange}
          type="text" />
      </FormGroup>
      <Button block className="btn-round" color="default" type="submit">
        Continue
      </Button>
      </form>

      {message ? <Message message={message}/> : null}

  </Modal>
</>

)

  }

    return (
      <>

          <Row>
            <Col lg="3" md="6" sm="6">
              <Card className="card-stats">
                <CardBody>
                  <Row>
                    <Col md="4" xs="5">
                      <Recharge />
                    </Col>
                    <Col md="8" xs="7">

Last Transaction

                        <CardTitle tag="p">315 Units</CardTitle>

                    </Col>
                  </Row>
                </CardBody>
                <CardFooter>

                     Get help

                </CardFooter>
              </Card>
            </Col>
          <Row>
          <Col md="12">
              <Card className="card-plain">
                <CardHeader>
                  <CardTitle tag="h4">Transactions</CardTitle>

                    A list of your previous transactions

                </CardHeader>
                <CardBody>

                        Date
                        Amount
                        Token
                        Action

                            {
                                transactions.map(transaction  =>{
                                    return  (
<TransactionItem key={transaction._id} transaction={transaction} />

)
                                })
                            }

                </CardBody>
              </Card>
            </Col>
          </Row>

      </>
    );
  }

export default Dashboard;```

答: I moved the modal to another page and imported it into the dashboard. Works fine now.</p>


问:
how to replace picture and check for collision with new image and and a moving image in pygame
I'm making a pygame game where a player is moving around on a screen and can buy items from a shop(bombs). I'm able to drop the bombs, now I need to replace the bomb image with an explosion image after 3 secs and check for collision with the enemy. I'm attaching my whole code along with some screenshots for reference. Any help is appreciated, thank you

```<code>import pygame
import random

pygame.font.init()

width = 900
height = 600

screen = pygame.display.set_mode([width, height])

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
             pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
             pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]

walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
            pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
            pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]

char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20,20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40,40))
# char_rect = char.get_rect()

enemy_Left = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
            pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
            pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png')]

x = 50
y = 50
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0

enemy_vel = 2
enemy_list = []

shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))

clock = pygame.time.Clock()
FPS = 60

font = pygame.font.Font('freesansbold.ttf', 32)
items_font = pygame.font.Font('freesansbold.ttf', 16)

bombs =[]
bag = {'bomb': 0}
print(bag["bomb"])

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def draw(self, win, outline=None):

        # Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)

        pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)

        if self.text != '':
            font = pygame.font.SysFont('comicsans', 20)
            text = font.render(self.text, 1, (0, 0, 0))
            win.blit(text, (
                self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

def shop_run():
    shop_bomb = Button((0, 200, 0), 820, 150, 60, 20, text="Bomb_b")
    bright_green = (0, 255, 0)
    green = (0, 200, 0)
    shop_bomb.draw(screen)

def redrawGameWindow():
    global walkCount
    global font
    global bag
    global items_font
    global enemy_list
    screen.fill([166, 166, 166])
    for five_enemies in range(6):
        random_enemy_location_y = random.randrange(100, 400)
        random_enemy_location_x = random.randrange(800, 840)
        enemy_list.append([random_enemy_location_x, random_enemy_location_y])

    for enemies in range(6):
        screen.blit(enemy_Left[enemies], enemy_list[enemies])
        enemy_list[enemies][0] -= 0.3

    pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
    if x + char.get_width() < 60 and y + char.get_height() < 60:
        shop_run()

    screen.blit(shop, (0, 0))
    screen.blit(font.render("Menu", True, (255,255,255)),(805, 10))
    screen.blit(items_font.render("Bombs: "+ str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
    # screen.blit(bomb_explosion, (450, 300))
    if walkCount + 1 >= 27:
        walkCount = 0

    if left:
        screen.blit(walkLeft[walkCount // 3], (x, y))
        walkCount += 1

    elif right:
        screen.blit(walkRight[walkCount // 3], (x, y))
        walkCount += 1

    elif down:
        screen.blit(char, (x, y))
        walkcount = 0

    elif up:
        screen.blit(char, (x, y))
        walkcount = 0

    else:
        screen.blit(char, (x, y))
        walkCount = 0

    for pos in bombs:
        screen.blit(bomb_pic, pos)

    pygame.display.update()

def main():
    run = True
    # shopper()
    pygame.display.set_caption("bomb-mania")

    global x
    global y
    global width
    global height
    global vel

    global isJump
    global jumpCount

    global left
    global right
    global down
    global up

    global walkCount

    global bomb_pic

    global font
    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if x + char.get_width() < 60 and y + char.get_height() < 60:
                buy = pygame.key.get_pressed()
                if buy[pygame.K_b]:
                    bag["bomb"] += 1
                    print(bag["bomb"])

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and bag["bomb"] >= 1:
                    bombs.append(((x + (char.get_width()/2)),( y + (char.get_height() - 20))))
                    bag["bomb"] -= 1

        redrawGameWindow()

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and x > vel - 15:
            x -= vel
            left = True
            right = False
            down = False
            up = False

        elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
            x += vel
            left = False
            right = True
            down = False
            up = False

        elif keys[pygame.K_DOWN] and y < 600 - height:
            y += vel
            left = False
            right = False
            down = True
            up = False

        elif keys[pygame.K_UP] and y > vel - 15:
            y -= vel
            left = False
            right = False
            down = False
            up = True

        else:
            left = False
            right = False
            down = False
            up = False
            walkCount = 0

        clock.tick(FPS)
        pygame.display.flip()

main()
</code>```

enemies are moving towards the left

able to drop bombs

able to buy bombs from the shop

I'm adding a code below please help me troubleshoot and debug this

```<code>import pygame
import random

pygame.font.init()

width = 900
height = 600

screen = pygame.display.set_mode([width, height])

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
             pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
             pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]

walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
            pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
            pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]

char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20,20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40,40))
# char_rect = char.get_rect()

enemy_Left = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
            pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
            pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png')]

x = 50
y = 50
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0

enemy_vel = 2
enemy_list = []

shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))

clock = pygame.time.Clock()
FPS = 60

font = pygame.font.Font('freesansbold.ttf', 32)
items_font = pygame.font.Font('freesansbold.ttf', 16)

bombs =[]
bag = {'bomb': 0}

bomb_timer = {"bomb0":0}
bomb_placed = False

bombCount = 1
bombs_dict = {"bomb0": False}
bombTimers = []

explosion_dict = {"explosion0": False}
print(bag["bomb"])

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def draw(self, win, outline=None):

        # Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)

        pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)

        if self.text != '':
            font = pygame.font.SysFont('comicsans', 20)
            text = font.render(self.text, 1, (0, 0, 0))
            win.blit(text, (
                self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

def shop_run():
    shop_bomb = Button((0, 200, 0), 820, 150, 60, 20, text="Bomb_b")
    bright_green = (0, 255, 0)
    green = (0, 200, 0)
    shop_bomb.draw(screen)

def redrawGameWindow():
    global walkCount
    global font
    global bag
    global items_font
    global enemy_list
    global bomb_timer
    global bomb_placed
    global explosion_dict

    screen.fill([166, 166, 166])
    for five_enemies in range(6):
        random_enemy_location_y = random.randrange(100, 400)
        random_enemy_location_x = random.randrange(800, 840)
        enemy_list.append([random_enemy_location_x, random_enemy_location_y])

    for enemies in range(6):
        screen.blit(enemy_Left[enemies], enemy_list[enemies])
        enemy_list[enemies][0] -= 0.3

    pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
    if x + char.get_width() < 60 and y + char.get_height() < 60:
        shop_run()

    screen.blit(shop, (0, 0))
    screen.blit(font.render("Menu", True, (255,255,255)),(805, 10))
    screen.blit(items_font.render("Bombs: "+ str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
    # screen.blit(bomb_explosion, (450, 300))
    if walkCount + 1 >= 27:
        walkCount = 0

    if left:
        screen.blit(walkLeft[walkCount // 3], (x, y))
        walkCount += 1

    elif right:
        screen.blit(walkRight[walkCount // 3], (x, y))
        walkCount += 1

    elif down:
        screen.blit(char, (x, y))
        walkcount = 0

    elif up:
        screen.blit(char, (x, y))
        walkcount = 0

    else:
        screen.blit(char, (x, y))
        walkCount = 0

    for pos in bombs:
        for i in bombs_dict:
            if bombs_dict["bomb"+str(bag["bomb"])]:
                screen.blit(bomb_pic, pos)
                bomb_timer["bomb"+str(bag["bomb"])] += clock.get_time()
                if bomb_timer["bomb"+str(bag["bomb"])] >= 3000:
                    bombs_dict["bomb"+str(bag["bomb"])] = False
                    explosion_dict["explosion" + str(bag["bomb"])] = True
                    del bombs_dict["bomb"+str(bag["bomb"])]

            else:
                if explosion_dict["explosion" + str(bag["bomb"])]:
                    screen.blit(bomb_explosion, (pos))

                    if bomb_timer["bomb"+str(bag["bomb"])] >= 5000:
                        explosion_dict["explosion" + str(bag["bomb"])] = False
                        del explosion_dict["explosion" + str(bag["bomb"])]

    pygame.display.update()

def main():
    run = True
    pygame.display.set_caption("bomb-mania")

    global x
    global y
    global width
    global height
    global vel

    global isJump
    global jumpCount

    global left
    global right
    global down
    global up

    global walkCount

    global bomb_pic

    global font

    global bombs_dict

    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if x + char.get_width() < 60 and y + char.get_height() < 60:
                buy = pygame.key.get_pressed()
                if buy[pygame.K_b]:
                    bag["bomb"] += 1
                    bombs_dict["bomb"+str(bag["bomb"])] = False
                    print(bag["bomb"])

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and bag["bomb"] >= 1:
                    bombs.append(((x + (char.get_width()/2)),( y + (char.get_height() - 20))))
                    bombs_dict["bomb"+str(bag["bomb"])] = True

                    bag["bomb"] -= 1

        redrawGameWindow()

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and x > vel - 15:
            x -= vel
            left = True
            right = False
            down = False
            up = False

        elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
            x += vel
            left = False
            right = True
            down = False
            up = False

        elif keys[pygame.K_DOWN] and y < 600 - height:
            y += vel
            left = False
            right = False
            down = True
            up = False

        elif keys[pygame.K_UP] and y > vel - 15:
            y -= vel
            left = False
            right = False
            down = False
            up = True

        else:
            left = False
            right = False
            down = False
            up = False
            walkCount = 0

        clock.tick(FPS)
        pygame.display.flip()

main()
</code>```

答:
Look at pygame.time.Clock(). If you set an FPS rate (say 20), All you have to do is:

```<code>myClock = pg.time.Clock()
FPS = 20
bomb_placed = True
bomb_timer = 0
main_loop():
    myClock.tick(FPS) # This will keep your FPS at 20 or below so you can estimate time
    if bomb_placed:
        bomb_timer += myClock.get_time()
        if bomb_timer >= 3000:
            # Draw the bomb explosion to the screen
        if bomb_timer >= 5000:
            bomb_timer = 0
            bomb_placed = False  # Stops displaying the bomb explosion
</code>```

Hope that helped. Feel free to check out the pygame docs on the subject:

https://www.pygame.org/docs/ref/time.html#pygame.time.Clock.get_time

Example for multiple bombs:

```<code>myClock = pg.time.Clock()

FPS = 20

bombA, bombB, bombC = False, False, False
bombA_timer, bombB_timer, bombC_timer = 0, 0, 0
bombs = [bombA, bombB, bombC]
bomb_timers = [bombA_timer, bombB_timer, bombC_timer]

main_loop():
    myClock.tick(FPS)
    for i in len(bombs):
        if bombs[i]:
            bomb_timers[i] += myClock.get_time()
            if bomb_timers[i] >= 3000:
                draw_explosion()
        if bomb_timer >= 5000:
            bomb_timers[i] = 0
            bomb_placed[i] = False
</code>```

This example simply loops through each of the bomb variables that represent the possible bombs on the screen- in this case a max of 3.

For lots of bombs, first create two dictionaries to hold the values of the bombs (active or not active) and their respective timers. Then loop through each of the bombs and, if the bomb is active, update the timer accordingly:

```<code>bombs = {"bomb0": False}  # Create dictionaries for the bombs and their timers, with 0-1 entries. (I did one to show you what it looks like).
bombTimers = {bombTimer0: 0}
main_loop():
    myClock.tick(FPS)
    for i in len(bombs):  # For each bomb you have created
        bombName = "bomb" + str(i)  # get the name of the bomb and corresponding timer
        timerName = "bombTimer" + str(i)
        if bombs[bombName]:  # If the bomg has a value of True:
            bombTimers[timerName] += myClock.get_time()  # Update the timer
            if bombTimers[timerName] >= 3000:  # Check if you need to draw the explosion
                draw_explosion()
        if bomb_timer >= 5000:  # Check if the bomb animation is over, and reset the bomb so that it can be used again in the future
            bombTimers[timerName] = 0
            bombs[bombName] = False
</code>```

This code works exactly the same as the previous example, but it is much easier to work with. You can easily add more bombs while not starting with an unnecessary amount, like so:

```<code>bombCount = 1
bombs = {"bomb0": False}
bombTimers = {"bombTimer0": 0}
main_loop():
    if player_placed_bomb():  # When the player drops a bomb in your game:
        placed = False  # Make a variable saying that you have not activaded the bomb and timer yet
        for key, val in bombs:  # For each bomb in the bombs dictionary:
            if not val:  # If the value of that bomb is False (Not being used):
                val = True  # Activates the bomb that was already created
                placed = True  # Updates the placed variable indicating that you set a bomb to active
                break
        if not placed:  # After looping through the dictionary, if there were no inactive bomb variables:
            bombs["bomb" + str(bombCounter)] = True  # Create a new bomb in your dictionary, with a unique name.
            bombTimers["bombTimer" + str(bombCounter)] = 0  # Created a new corresponding timer
            bombCounter += 1  # Add 1 to the bombCounter, which is used to create the unique name of the next bomb you create.

    # Rest of main_loop()
</code>```

This code ensures that you are working with the smallest dictionaries possible to reduce unneeded computation power. When a bomb explodes, it will become false and it's matching timer reset. The first if loop in the code above ensures that all existing bombs are active, and if not reuses the old bomb and timer. If all bombs are being used, It creates new entries in the dictionaries to allow for more bombs.

I added an unnecesarry amount of comments, but I hope it makes it more understandable for you. Let me know if you have more questions on how this works. If you are unfamiliar with python dict() objects, there are lots of resources on the internet that explain them thoughroughly.
Disclaimer: I haven't actually ran the code, but it should function how it is supposed to. Let me know if it doesn't.

Here are some thoughts on the reformed code:

You use "str(bag["bombs"])" quite a bit in your code- consider defining a variable: b = str(bag["bombs"]), and using that. It would make it much simpler.

I don't know why you delete the "bombs_dict" and "explosions_dict" entries after you are finished with them. The way your loop is set up, I will result in an error. I would suggest rather than deleting the entries, you keep them and attempt to reuse them, as shown in the code snippet above.

Or, if you like deleting them, you need to figure out a way to rename certain keys in your dictionaries so that the names are in order. (if you delete bomb2 from bombs_dict, and you have bomb1 and bomb3, you need to change bomb3 to bomb2 or the loop wont work as intended). You will also need to alter your bombCount variable accordingly.

Body:
I'm making a pygame game where a player is moving around on a screen and can buy items from a shop(bombs). I'm able to drop the bombs, now I need to replace the bomb image with an explosion image after 3 secs and check for collision with the enemy. I'm attaching my whole code along with some screenshots for reference. Any help is appreciated, thank you

import pygame
import random

pygame.font.init()

width = 900
height = 600

screen = pygame.display.set_mode([width, height])

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
             pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
             pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]

walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
            pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
            pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]

char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20,20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40,40))
# char_rect = char.get_rect()

enemy_Left = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
            pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
            pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png')]

x = 50
y = 50
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0

enemy_vel = 2
enemy_list = []

shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))

clock = pygame.time.Clock()
FPS = 60

font = pygame.font.Font('freesansbold.ttf', 32)
items_font = pygame.font.Font('freesansbold.ttf', 16)

bombs =[]
bag = {'bomb': 0}
print(bag["bomb"])

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def draw(self, win, outline=None):

        # Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)

        pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)

        if self.text != '':
            font = pygame.font.SysFont('comicsans', 20)
            text = font.render(self.text, 1, (0, 0, 0))
            win.blit(text, (
                self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

def shop_run():
    shop_bomb = Button((0, 200, 0), 820, 150, 60, 20, text="Bomb_b")
    bright_green = (0, 255, 0)
    green = (0, 200, 0)
    shop_bomb.draw(screen)

def redrawGameWindow():
    global walkCount
    global font
    global bag
    global items_font
    global enemy_list
    screen.fill([166, 166, 166])
    for five_enemies in range(6):
        random_enemy_location_y = random.randrange(100, 400)
        random_enemy_location_x = random.randrange(800, 840)
        enemy_list.append([random_enemy_location_x, random_enemy_location_y])

    for enemies in range(6):
        screen.blit(enemy_Left[enemies], enemy_list[enemies])
        enemy_list[enemies][0] -= 0.3

    pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
    if x + char.get_width() < 60 and y + char.get_height() < 60:
        shop_run()

    screen.blit(shop, (0, 0))
    screen.blit(font.render("Menu", True, (255,255,255)),(805, 10))
    screen.blit(items_font.render("Bombs: "+ str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
    # screen.blit(bomb_explosion, (450, 300))
    if walkCount + 1 >= 27:
        walkCount = 0

    if left:
        screen.blit(walkLeft[walkCount // 3], (x, y))
        walkCount += 1

    elif right:
        screen.blit(walkRight[walkCount // 3], (x, y))
        walkCount += 1

    elif down:
        screen.blit(char, (x, y))
        walkcount = 0

    elif up:
        screen.blit(char, (x, y))
        walkcount = 0

    else:
        screen.blit(char, (x, y))
        walkCount = 0

    for pos in bombs:
        screen.blit(bomb_pic, pos)

    pygame.display.update()

def main():
    run = True
    # shopper()
    pygame.display.set_caption("bomb-mania")

    global x
    global y
    global width
    global height
    global vel

    global isJump
    global jumpCount

    global left
    global right
    global down
    global up

    global walkCount

    global bomb_pic

    global font
    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if x + char.get_width() < 60 and y + char.get_height() < 60:
                buy = pygame.key.get_pressed()
                if buy[pygame.K_b]:
                    bag["bomb"] += 1
                    print(bag["bomb"])

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and bag["bomb"] >= 1:
                    bombs.append(((x + (char.get_width()/2)),( y + (char.get_height() - 20))))
                    bag["bomb"] -= 1

        redrawGameWindow()

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and x > vel - 15:
            x -= vel
            left = True
            right = False
            down = False
            up = False

        elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
            x += vel
            left = False
            right = True
            down = False
            up = False

        elif keys[pygame.K_DOWN] and y < 600 - height:
            y += vel
            left = False
            right = False
            down = True
            up = False

        elif keys[pygame.K_UP] and y > vel - 15:
            y -= vel
            left = False
            right = False
            down = False
            up = True

        else:
            left = False
            right = False
            down = False
            up = False
            walkCount = 0

        clock.tick(FPS)
        pygame.display.flip()

main()

enemies are moving towards the left

able to drop bombs

able to buy bombs from the shop

I'm adding a code below please help me troubleshoot and debug this

import pygame
import random

pygame.font.init()

width = 900
height = 600

screen = pygame.display.set_mode([width, height])

walkRight = [pygame.image.load('R1.png'), pygame.image.load('R2.png'), pygame.image.load('R3.png'),
             pygame.image.load('R4.png'), pygame.image.load('R5.png'), pygame.image.load('R6.png'),
             pygame.image.load('R7.png'), pygame.image.load('R8.png'), pygame.image.load('R9.png')]

walkLeft = [pygame.image.load('L1.png'), pygame.image.load('L2.png'), pygame.image.load('L3.png'),
            pygame.image.load('L4.png'), pygame.image.load('L5.png'), pygame.image.load('L6.png'),
            pygame.image.load('L7.png'), pygame.image.load('L8.png'), pygame.image.load('L9.png')]

char = pygame.image.load('standing.png')
bomb_pic = pygame.transform.scale(pygame.image.load('bomb.png'), (20,20))
bomb_explosion = pygame.transform.scale(pygame.image.load('explosion1.png'), (40,40))
# char_rect = char.get_rect()

enemy_Left = [pygame.image.load('L1E.png'), pygame.image.load('L2E.png'), pygame.image.load('L3E.png'),
            pygame.image.load('L4E.png'), pygame.image.load('L5E.png'), pygame.image.load('L6E.png'),
            pygame.image.load('L7E.png'), pygame.image.load('L8E.png'), pygame.image.load('L9E.png')]

x = 50
y = 50
width = 40
height = 60
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
down = False
up = False
walkCount = 0

enemy_vel = 2
enemy_list = []

shop = pygame.transform.scale(pygame.image.load("shop.png"), (60, 60))

clock = pygame.time.Clock()
FPS = 60

font = pygame.font.Font('freesansbold.ttf', 32)
items_font = pygame.font.Font('freesansbold.ttf', 16)

bombs =[]
bag = {'bomb': 0}

bomb_timer = {"bomb0":0}
bomb_placed = False

bombCount = 1
bombs_dict = {"bomb0": False}
bombTimers = []

explosion_dict = {"explosion0": False}
print(bag["bomb"])

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text

    def draw(self, win, outline=None):

        # Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)

        pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)

        if self.text != '':
            font = pygame.font.SysFont('comicsans', 20)
            text = font.render(self.text, 1, (0, 0, 0))
            win.blit(text, (
                self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))

def shop_run():
    shop_bomb = Button((0, 200, 0), 820, 150, 60, 20, text="Bomb_b")
    bright_green = (0, 255, 0)
    green = (0, 200, 0)
    shop_bomb.draw(screen)

def redrawGameWindow():
    global walkCount
    global font
    global bag
    global items_font
    global enemy_list
    global bomb_timer
    global bomb_placed
    global explosion_dict

    screen.fill([166, 166, 166])
    for five_enemies in range(6):
        random_enemy_location_y = random.randrange(100, 400)
        random_enemy_location_x = random.randrange(800, 840)
        enemy_list.append([random_enemy_location_x, random_enemy_location_y])

    for enemies in range(6):
        screen.blit(enemy_Left[enemies], enemy_list[enemies])
        enemy_list[enemies][0] -= 0.3

    pygame.draw.rect(screen, (0, 0, 0), (800, 0, 100, 600))
    if x + char.get_width() < 60 and y + char.get_height() < 60:
        shop_run()

    screen.blit(shop, (0, 0))
    screen.blit(font.render("Menu", True, (255,255,255)),(805, 10))
    screen.blit(items_font.render("Bombs: "+ str(bag["bomb"]), True, (255, 255, 255)), (805, 550))
    # screen.blit(bomb_explosion, (450, 300))
    if walkCount + 1 >= 27:
        walkCount = 0

    if left:
        screen.blit(walkLeft[walkCount // 3], (x, y))
        walkCount += 1

    elif right:
        screen.blit(walkRight[walkCount // 3], (x, y))
        walkCount += 1

    elif down:
        screen.blit(char, (x, y))
        walkcount = 0

    elif up:
        screen.blit(char, (x, y))
        walkcount = 0

    else:
        screen.blit(char, (x, y))
        walkCount = 0

    for pos in bombs:
        for i in bombs_dict:
            if bombs_dict["bomb"+str(bag["bomb"])]:
                screen.blit(bomb_pic, pos)
                bomb_timer["bomb"+str(bag["bomb"])] += clock.get_time()
                if bomb_timer["bomb"+str(bag["bomb"])] >= 3000:
                    bombs_dict["bomb"+str(bag["bomb"])] = False
                    explosion_dict["explosion" + str(bag["bomb"])] = True
                    del bombs_dict["bomb"+str(bag["bomb"])]

            else:
                if explosion_dict["explosion" + str(bag["bomb"])]:
                    screen.blit(bomb_explosion, (pos))

                    if bomb_timer["bomb"+str(bag["bomb"])] >= 5000:
                        explosion_dict["explosion" + str(bag["bomb"])] = False
                        del explosion_dict["explosion" + str(bag["bomb"])]

    pygame.display.update()

def main():
    run = True
    pygame.display.set_caption("bomb-mania")

    global x
    global y
    global width
    global height
    global vel

    global isJump
    global jumpCount

    global left
    global right
    global down
    global up

    global walkCount

    global bomb_pic

    global font

    global bombs_dict

    while run:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if x + char.get_width() < 60 and y + char.get_height() < 60:
                buy = pygame.key.get_pressed()
                if buy[pygame.K_b]:
                    bag["bomb"] += 1
                    bombs_dict["bomb"+str(bag["bomb"])] = False
                    print(bag["bomb"])

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and bag["bomb"] >= 1:
                    bombs.append(((x + (char.get_width()/2)),( y + (char.get_height() - 20))))
                    bombs_dict["bomb"+str(bag["bomb"])] = True

                    bag["bomb"] -= 1

        redrawGameWindow()

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and x > vel - 15:
            x -= vel
            left = True
            right = False
            down = False
            up = False

        elif keys[pygame.K_RIGHT] and x < 800 - vel - width:
            x += vel
            left = False
            right = True
            down = False
            up = False

        elif keys[pygame.K_DOWN] and y < 600 - height:
            y += vel
            left = False
            right = False
            down = True
            up = False

        elif keys[pygame.K_UP] and y > vel - 15:
            y -= vel
            left = False
            right = False
            down = False
            up = True

        else:
            left = False
            right = False
            down = False
            up = False
            walkCount = 0

        clock.tick(FPS)
        pygame.display.flip()

main()

Body:
Look at pygame.time.Clock(). If you set an FPS rate (say 20), All you have to do is:

myClock = pg.time.Clock()
FPS = 20
bomb_placed = True
bomb_timer = 0
main_loop():
    myClock.tick(FPS) # This will keep your FPS at 20 or below so you can estimate time
    if bomb_placed:
        bomb_timer += myClock.get_time()
        if bomb_timer >= 3000:
            # Draw the bomb explosion to the screen
        if bomb_timer >= 5000:
            bomb_timer = 0
            bomb_placed = False  # Stops displaying the bomb explosion

Hope that helped. Feel free to check out the pygame docs on the subject:

https://www.pygame.org/docs/ref/time.html#pygame.time.Clock.get_time

Example for multiple bombs:

myClock = pg.time.Clock()

FPS = 20

bombA, bombB, bombC = False, False, False
bombA_timer, bombB_timer, bombC_timer = 0, 0, 0
bombs = [bombA, bombB, bombC]
bomb_timers = [bombA_timer, bombB_timer, bombC_timer]

main_loop():
    myClock.tick(FPS)
    for i in len(bombs):
        if bombs[i]:
            bomb_timers[i] += myClock.get_time()
            if bomb_timers[i] >= 3000:
                draw_explosion()
        if bomb_timer >= 5000:
            bomb_timers[i] = 0
            bomb_placed[i] = False

This example simply loops through each of the bomb variables that represent the possible bombs on the screen- in this case a max of 3.

For lots of bombs, first create two dictionaries to hold the values of the bombs (active or not active) and their respective timers. Then loop through each of the bombs and, if the bomb is active, update the timer accordingly:

bombs = {"bomb0": False}  # Create dictionaries for the bombs and their timers, with 0-1 entries. (I did one to show you what it looks like).
bombTimers = {bombTimer0: 0}
main_loop():
    myClock.tick(FPS)
    for i in len(bombs):  # For each bomb you have created
        bombName = "bomb" + str(i)  # get the name of the bomb and corresponding timer
        timerName = "bombTimer" + str(i)
        if bombs[bombName]:  # If the bomg has a value of True:
            bombTimers[timerName] += myClock.get_time()  # Update the timer
            if bombTimers[timerName] >= 3000:  # Check if you need to draw the explosion
                draw_explosion()
        if bomb_timer >= 5000:  # Check if the bomb animation is over, and reset the bomb so that it can be used again in the future
            bombTimers[timerName] = 0
            bombs[bombName] = False

This code works exactly the same as the previous example, but it is much easier to work with. You can easily add more bombs while not starting with an unnecessary amount, like so:

bombCount = 1
bombs = {"bomb0": False}
bombTimers = {"bombTimer0": 0}
main_loop():
    if player_placed_bomb():  # When the player drops a bomb in your game:
        placed = False  # Make a variable saying that you have not activaded the bomb and timer yet
        for key, val in bombs:  # For each bomb in the bombs dictionary:
            if not val:  # If the value of that bomb is False (Not being used):
                val = True  # Activates the bomb that was already created
                placed = True  # Updates the placed variable indicating that you set a bomb to active
                break
        if not placed:  # After looping through the dictionary, if there were no inactive bomb variables:
            bombs["bomb" + str(bombCounter)] = True  # Create a new bomb in your dictionary, with a unique name.
            bombTimers["bombTimer" + str(bombCounter)] = 0  # Created a new corresponding timer
            bombCounter += 1  # Add 1 to the bombCounter, which is used to create the unique name of the next bomb you create.

    # Rest of main_loop()

This code ensures that you are working with the smallest dictionaries possible to reduce unneeded computation power. When a bomb explodes, it will become false and it's matching timer reset. The first if loop in the code above ensures that all existing bombs are active, and if not reuses the old bomb and timer. If all bombs are being used, It creates new entries in the dictionaries to allow for more bombs.

I added an unnecesarry amount of comments, but I hope it makes it more understandable for you. Let me know if you have more questions on how this works. If you are unfamiliar with python dict() objects, there are lots of resources on the internet that explain them thoughroughly.
Disclaimer: I haven't actually ran the code, but it should function how it is supposed to. Let me know if it doesn't.

Here are some thoughts on the reformed code:

You use "str(bag["bombs"])" quite a bit in your code- consider defining a variable: b = str(bag["bombs"]), and using that. It would make it much simpler.

I don't know why you delete the "bombs_dict" and "explosions_dict" entries after you are finished with them. The way your loop is set up, I will result in an error. I would suggest rather than deleting the entries, you keep them and attempt to reuse them, as shown in the code snippet above.

Or, if you like deleting them, you need to figure out a way to rename certain keys in your dictionaries so that the names are in order. (if you delete bomb2 from bombs_dict, and you have bomb1 and bomb3, you need to change bomb3 to bomb2 or the loop wont work as intended). You will also need to alter your bombCount variable accordingly.


问:
Filter based on user input - LiveData, Recycler, RoomView
I have an SQLite Database for my Android App. Database has a table for properties , and another table for the repairs at each property.

Table repairs  :

```<code>@Entity(tableName = "repairs",
        indices = {@Index(value = "repairID", unique = true), @Index("repairPropID")})

public class MYRepairs
{
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "repid")
    public int id;

    @ColumnInfo(name = "repairID")
    @NonNull
    public String repairID;

    @ColumnInfo(name = "repairPropID")
    public int repairPropID;
}
</code>```

...

and then RepairsDao.java

```<code> @Dao
    public interface MyRepairsDao
    {
        @Query("SELECT * FROM repairs WHERE repid = :repid LIMIT 1")
        MYRepairs findRepairById(String repid);

        @Query("SELECT * FROM repairs WHERE repairPropID = :repairPropID")
        MYRepairs findRepairByPropID(int repairPropID);

        @Query("SELECT * FROM repairs ORDER BY repairPropID ASC")
        LiveData<List<MYRepairs>> getAllRepairs();

 @Query("SELECT * FROM repairs WHERE repairPropID = :repairPropID")
    LiveData<List<MYRepairs>> getPropertyRepairs(int repairPropID);

    }
</code>```

In the ViewModel:

```<code>   public class repairViewModel extends AndroidViewModel
    {
        private MyRepairsDao myRepairDao;
        private LiveData<List<MYRepairs>> repairLiveData;
        private LiveData<List<MYRepairs>> repairPropertyLiveData;
        private LiveData<String> filterLiveData = new MutableLiveData<String>();

        public repairViewModel(@NonNull Application application)
        {
            super(application);
            myRepairDao = DogwoodDatabase.getDatabase(application).repairDao();
            repairLiveData = myRepairDao.getAllRepairs();
            repairPropertyLiveData = myRepairDao.getPropertyRepairs(propertyID);
        }

        public LiveData<List<MYRepairs>> getAllRepairs()
        {
            return repairLiveData;
        }

        public LiveData<List<MYRepairs>> getPropertyRepairs(int propertyID)
        {
            return repairPropertyLiveData;
        }
</code>```

And in the RecyclerView.Adapter:

```<code>public class repairListAdapter extends RecyclerView.Adapter<repairListAdapter.RepairViewHolder>
{
@NonNull
        @Override
        public repairListAdapter.RepairViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
        {
            final View itemView = layoutInflater.inflate(R.layout.repaircontent, parent, false);
            return new repairListAdapter.RepairViewHolder(itemView);
        }
</code>```

In the repairFragment - we only want to view the repairs for a user selected property. Property Code propertyID  is received by the repairFragement. It is known to the initData()

```<code>   public class repairFragment extends Fragment
    {

        private repairListAdapter repairListAdapter;
        private repairViewModel repairViewModel;

        public void onCreate(@Nullable Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            propertyID = getArguments().getString("ARG_PROPNUM_ID");
            propNumID = Integer.parseInt(propertyID);
            initData();
        }

     private void initData()
        {
            Log.e ("INIT", "ID is " + propertyID);

            repairViewModel = new
                   ViewModelProvider(this).get(repairViewModel.class);

repairViewModel.getPropertyRepairs(propertyID).observe(this, new Observer<List<MYRepairs>>()
            {
                @Override
                public void onChanged(@Nullable List<MYRepairs> MYRepairs)
                {
                    repairListAdapter.setMYRepairList(MYRepairs);
                }
            });

        }
</code>```

This returns NO RECORDS.
In an ideal world, my properties would have no repairs, but I do not live in that world!

I have scoured this board for help on filtering .

Can you help me with how to filter for only the repairs for a user selected property (propertyID).

Thanks, Rachael

答:
Oh my! I figured it out. </p>

<p>In repairViewModel: </p>

```<code>public LiveData<List<MYRepairs>> getPropertyRepairs(int propertyID)
    {

        repairPropertyLiveData = myRepairDao.getPropertyRepairs(propertyID);
        return repairPropertyLiveData;
    }
</code>```

Body:
I have an SQLite Database for my Android App. Database has a table for properties , and another table for the repairs at each property.

Table repairs  :

@Entity(tableName = "repairs",
        indices = {@Index(value = "repairID", unique = true), @Index("repairPropID")})

public class MYRepairs
{
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "repid")
    public int id;

    @ColumnInfo(name = "repairID")
    @NonNull
    public String repairID;

    @ColumnInfo(name = "repairPropID")
    public int repairPropID;
}

...

and then RepairsDao.java

 @Dao
    public interface MyRepairsDao
    {
        @Query("SELECT * FROM repairs WHERE repid = :repid LIMIT 1")
        MYRepairs findRepairById(String repid);

        @Query("SELECT * FROM repairs WHERE repairPropID = :repairPropID")
        MYRepairs findRepairByPropID(int repairPropID);

        @Query("SELECT * FROM repairs ORDER BY repairPropID ASC")
        LiveData<List<MYRepairs>> getAllRepairs();

 @Query("SELECT * FROM repairs WHERE repairPropID = :repairPropID")
    LiveData<List<MYRepairs>> getPropertyRepairs(int repairPropID);

    }

In the ViewModel:

   public class repairViewModel extends AndroidViewModel
    {
        private MyRepairsDao myRepairDao;
        private LiveData<List<MYRepairs>> repairLiveData;
        private LiveData<List<MYRepairs>> repairPropertyLiveData;
        private LiveData<String> filterLiveData = new MutableLiveData<String>();

        public repairViewModel(@NonNull Application application)
        {
            super(application);
            myRepairDao = DogwoodDatabase.getDatabase(application).repairDao();
            repairLiveData = myRepairDao.getAllRepairs();
            repairPropertyLiveData = myRepairDao.getPropertyRepairs(propertyID);
        }

        public LiveData<List<MYRepairs>> getAllRepairs()
        {
            return repairLiveData;
        }

        public LiveData<List<MYRepairs>> getPropertyRepairs(int propertyID)
        {
            return repairPropertyLiveData;
        }

And in the RecyclerView.Adapter:

public class repairListAdapter extends RecyclerView.Adapter<repairListAdapter.RepairViewHolder>
{
@NonNull
        @Override
        public repairListAdapter.RepairViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
        {
            final View itemView = layoutInflater.inflate(R.layout.repaircontent, parent, false);
            return new repairListAdapter.RepairViewHolder(itemView);
        }

In the repairFragment - we only want to view the repairs for a user selected property. Property Code propertyID  is received by the repairFragement. It is known to the initData()

   public class repairFragment extends Fragment
    {

        private repairListAdapter repairListAdapter;
        private repairViewModel repairViewModel;

        public void onCreate(@Nullable Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            propertyID = getArguments().getString("ARG_PROPNUM_ID");
            propNumID = Integer.parseInt(propertyID);
            initData();
        }

     private void initData()
        {
            Log.e ("INIT", "ID is " + propertyID);

            repairViewModel = new
                   ViewModelProvider(this).get(repairViewModel.class);

repairViewModel.getPropertyRepairs(propertyID).observe(this, new Observer<List<MYRepairs>>()
            {
                @Override
                public void onChanged(@Nullable List<MYRepairs> MYRepairs)
                {
                    repairListAdapter.setMYRepairList(MYRepairs);
                }
            });

        }

This returns NO RECORDS.
In an ideal world, my properties would have no repairs, but I do not live in that world!

I have scoured this board for help on filtering .

Can you help me with how to filter for only the repairs for a user selected property (propertyID).

Thanks, Rachael

Body:
Oh my! I figured it out.

In repairViewModel:

public LiveData<List<MYRepairs>> getPropertyRepairs(int propertyID)
    {

        repairPropertyLiveData = myRepairDao.getPropertyRepairs(propertyID);
        return repairPropertyLiveData;
    }


问:
Asp.Net Core Identity, IdentityUser.Email versus UserManage<IdentityUser>.GetEmailAsync(IdentityUser user)
I am reviewing the scaffolded identity account management pages in an Asp.Net Core website project. The OnGetAsync() in the change email Razor page loads the current user using UserManager.GetUserAsync().
It then calls another method to load the email address and IsEmailConfirmed value into properties of the page model.

The load method uses UserManager.GetEmailAsync(user) instead of just user.Email. Why would the Microsoft coders do that?

It does the same thing for the IsEmailConfirmed by using UserManager.IsEmailConfirmedAsync(user) instead of just user.IsEmailConfirmed.

What am I missing?

```<code>public partial class Email : PageModel
{
  public string Email { get; set; }

  [BindProperty]
  public InputModel Input { get; set; }
  public bool IsEmailConfirmed { get; set; }

  public async Task<IActionResult> OnGetAsync()
  {
    var user = await _userManager.GetUserAsync(User);
    if (user == null)
    {
      return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }
    // user should be valid here.
    await LoadAsync(user);
    return Page();
  }

  protected async Task LoadAsync(IdentityUser user)
  {
    // user should be valid here.

    // Why not just "string email = user.Email"?
    string email = await _userManager.GetEmailAsync(user);
    Email = email;
    Input = new InputModel { NewEmail = email };

    // Why not just do "IsEmailConfirmed = user.IsEmailConfirmed"?
    IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
    }

  public class InputModel
  {
  [Required]
  [EmailAddress]
  [Display(Name = "New email")]
  public string NewEmail { get; set; }
  }
}```
```

答: That has to be an implementation issue. Looking at the UserManager class at github, the GetEmailAsync makes a request to the database and also the duo. Which is not proper since the first request already retrieves everything about the user. You can implement that yourself anyway.

Body:
I am reviewing the scaffolded identity account management pages in an Asp.Net Core website project. The OnGetAsync() in the change email Razor page loads the current user using UserManager.GetUserAsync().
It then calls another method to load the email address and IsEmailConfirmed value into properties of the page model.

The load method uses UserManager.GetEmailAsync(user) instead of just user.Email. Why would the Microsoft coders do that?

It does the same thing for the IsEmailConfirmed by using UserManager.IsEmailConfirmedAsync(user) instead of just user.IsEmailConfirmed.

What am I missing?

public partial class Email : PageModel
{
  public string Email { get; set; }

  [BindProperty]
  public InputModel Input { get; set; }
  public bool IsEmailConfirmed { get; set; }

  public async Task<IActionResult> OnGetAsync()
  {
    var user = await _userManager.GetUserAsync(User);
    if (user == null)
    {
      return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
    }
    // user should be valid here.
    await LoadAsync(user);
    return Page();
  }

  protected async Task LoadAsync(IdentityUser user)
  {
    // user should be valid here.

    // Why not just "string email = user.Email"?
    string email = await _userManager.GetEmailAsync(user);
    Email = email;
    Input = new InputModel { NewEmail = email };

    // Why not just do "IsEmailConfirmed = user.IsEmailConfirmed"?
    IsEmailConfirmed = await _userManager.IsEmailConfirmedAsync(user);
    }

  public class InputModel
  {
  [Required]
  [EmailAddress]
  [Display(Name = "New email")]
  public string NewEmail { get; set; }
  }
}```


问:
Can Kafka topic names be parameterised?
I've recently started experimenting with AsyncAPI as part of a project at work. My task is to see if we can use AsyncAPI to generate code to send test objects to our existing Kafka queues. I'm not familiar with Kafka.

I'm starting with the API specification at AsyncAPI playground, and trying to generate some Java Spring code from it. However, I've run into an issue in that, in the playground specification, channel names (which will correspond to Kafka topics) are parameterised, e.g. as:

```<code>smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured
</code>```

Is it possible to parameterise the Kafka topic in this way, such that the generated service has the following annotation?

```<code>@KafkaListener(topics = "smartylighting.streetlights.1.0.action.{streetlightId}.lighting.measured", groupId = "myGroupId")
</code>```

Or does this specification (which again, I'm just using to learn AsyncAPI) need to be changed so that topic names are invariant, and instead provide the street light ID as payload data?

Thanks in advance.

答:
This is currently one of missed features of the java-spring template.

parameters for topics are not supported

Please consider creation of a new issue with detail description of your case.

Title: Can Kafka topic names be parameterised?

Body:
I've recently started experimenting with AsyncAPI as part of a project at work. My task is to see if we can use AsyncAPI to generate code to send test objects to our existing Kafka queues. I'm not familiar with Kafka.

I'm starting with the API specification at AsyncAPI playground, and trying to generate some Java Spring code from it. However, I've run into an issue in that, in the playground specification, channel names (which will correspond to Kafka topics) are parameterised, e.g. as:

smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured

Is it possible to parameterise the Kafka topic in this way, such that the generated service has the following annotation?

@KafkaListener(topics = "smartylighting.streetlights.1.0.action.{streetlightId}.lighting.measured", groupId = "myGroupId")

Or does this specification (which again, I'm just using to learn AsyncAPI) need to be changed so that topic names are invariant, and instead provide the street light ID as payload data?

Thanks in advance.


问:
edit parent and children in same view
How would I edit a parent and collection of child objects in the same view? Any good tutorials on how to do this with mvc3 and automatic binding?

Much appreciated!

答:
The key would be to use the following syntax in your view for your child collection items:

```<code>data.Children.Index and data.Children[index].Properties
</code>```

Here is a simple example:

Model:

```<code>public class Parent
{
  public int FieldA { get; set; }
  public string FieldB { get; set; }
}

public class Child
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class ParentChildViewModel
{
  public Parent Master { get; set; }
  public List<Child> Children { get; set; }
}
</code>```

Controller:

```<code>public ActionResult Edit()
{
  return View(new ParentChildViewModel());
}

[HttpPost]
public ActionResult Edit(ParentChildViewModel data)
{
  // Save your objects
}
</code>```

View:

```<code>@model ParentChildViewModel
...
@using(Html.BeginForm())
{
  @Html.TextBoxFor(x => x.Master.FieldA);

  @{ int index = 0; }
  @foreach(var c in Model.Children)
  {
    @Html.Hidden("data.Children.Index", index);
    @Html.TextBox("data.Children[" + index + "].Name")
    @{ index++; }
  }
}
</code>```

On your controller you will receive on the .Children properties the changes made to the Name properties and on the .Master the changes made to the parent. The only trick is the data.Children syntax where data is the name of the variable name on you Controller. The data.Children.Index is required for each child and of course you have to increment the index.

Hope that help.

Title: edit parent and children in same view

Body:
The key would be to use the following syntax in your view for your child collection items:

data.Children.Index and data.Children[index].Properties

Here is a simple example:

Model:

public class Parent
{
  public int FieldA { get; set; }
  public string FieldB { get; set; }
}

public class Child
{
  public int Id { get; set; }
  public string Name { get; set; }
}

public class ParentChildViewModel
{
  public Parent Master { get; set; }
  public List<Child> Children { get; set; }
}

Controller:

public ActionResult Edit()
{
  return View(new ParentChildViewModel());
}

[HttpPost]
public ActionResult Edit(ParentChildViewModel data)
{
  // Save your objects
}

View:

@model ParentChildViewModel
...
@using(Html.BeginForm())
{
  @Html.TextBoxFor(x => x.Master.FieldA);

  @{ int index = 0; }
  @foreach(var c in Model.Children)
  {
    @Html.Hidden("data.Children.Index", index);
    @Html.TextBox("data.Children[" + index + "].Name")
    @{ index++; }
  }
}

On your controller you will receive on the .Children properties the changes made to the Name properties and on the .Master the changes made to the parent. The only trick is the data.Children syntax where data is the name of the variable name on you Controller. The data.Children.Index is required for each child and of course you have to increment the index.

Hope that help.


问:
Converting lines in to columns
I used this  script to generate the below output from server show /system1/swid*" |egrep -w "name|VersionString" | sed 's/^[ \t]*//;s/[ \t]*$//', but I am unable to convert these lines into columns. please help me to get some idea to convert this into columns.

```<code>name=iLO
VersionString=2.73 Feb 11 2020
name=System ROM
VersionString=P89 v2.76 (10/21/2019)
name=Redundant System ROM
VersionString=P89 v2.64 (10/17/2018)
name=Intelligent Provisioning
VersionString=2.70.75
</code>```

Required output

```<code>    name=iLO                            name=System ROM                             name=Redundant System ROM                   name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020      VersionString=P89 v2.76 (10/21/2019)        VersionString=P89 v2.64 (10/17/2018)        VersionString=2.70.75
</code>```

image

答:
If fancy utils are allowed, then using sed, datamash, and *Steve Kinzler's * align:

```<code>sed -n 's/.*/&\t/;N;s/\n//p' file |
datamash transpose | align  -j _ -g 3
</code>```

Output:

```<code>name=iLO                         name=System ROM                        name=Redundant System ROM              name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020   VersionString=P89 v2.76 (10/21/2019)   VersionString=P89 v2.64 (10/17/2018)   VersionString=2.70.75
</code>```

If center justified text is required, just add -a c a the end, like so:

```<code>sed -n 's/.*/&\t/;N;s/\n//p' file |
datamash transpose | align  -j _ -g 3 -a c
</code>```

Output:

```<code>           name=iLO                        name=System ROM                   name=Redundant System ROM         name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020   VersionString=P89 v2.76 (10/21/2019)   VersionString=P89 v2.64 (10/17/2018)       VersionString=2.70.75
</code>```

Title: Converting lines in to columns

Body:
I used this  script to generate the below output from server show /system1/swid*" |egrep -w "name|VersionString" | sed 's/^[ \t]*//;s/[ \t]*$//', but I am unable to convert these lines into columns. please help me to get some idea to convert this into columns.

name=iLO
VersionString=2.73 Feb 11 2020
name=System ROM
VersionString=P89 v2.76 (10/21/2019)
name=Redundant System ROM
VersionString=P89 v2.64 (10/17/2018)
name=Intelligent Provisioning
VersionString=2.70.75

Required output

    name=iLO                            name=System ROM                             name=Redundant System ROM                   name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020      VersionString=P89 v2.76 (10/21/2019)        VersionString=P89 v2.64 (10/17/2018)        VersionString=2.70.75

image

Body:
If fancy utils are allowed, then using sed, datamash, and *Steve Kinzler's * align:

sed -n 's/.*/&\t/;N;s/\n//p' file |
datamash transpose | align  -j _ -g 3

Output:

name=iLO                         name=System ROM                        name=Redundant System ROM              name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020   VersionString=P89 v2.76 (10/21/2019)   VersionString=P89 v2.64 (10/17/2018)   VersionString=2.70.75

If center justified text is required, just add -a c a the end, like so:

sed -n 's/.*/&\t/;N;s/\n//p' file |
datamash transpose | align  -j _ -g 3 -a c

Output:

           name=iLO                        name=System ROM                   name=Redundant System ROM         name=Intelligent Provisioning
VersionString=2.73 Feb 11 2020   VersionString=P89 v2.76 (10/21/2019)   VersionString=P89 v2.64 (10/17/2018)       VersionString=2.70.75


问:
Calling beam.io.WriteToBigQuery in a beam.DoFn
I've created a dataflow template with some parameters. When I write the data to BigQuery, I would like to make use of these parameters to determine which table it is supposed to write to. I've tried calling WriteToBigQuery in a ParDo as  suggested in the following link.

How can I write to Big Query using a runtime value provider in Apache Beam?

The pipeline ran successfully but it is not creating or loading data to BigQuery. Any idea what might be the issue?

```<code>def run():
  pipeline_options = PipelineOptions()
  pipeline_options.view_as(DebugOptions).experiments = ['use_beam_bq_sink']

  with beam.Pipeline(options=pipeline_options) as p:
    custom_options = pipeline_options.view_as(CustomOptions)

    _ = (
      p
      | beam.Create([None])
      | 'Year to periods' >> beam.ParDo(SplitYearToPeriod(custom_options.year))
      | 'Read plan data' >> beam.ParDo(GetPlanDataByPeriod(custom_options.secret_name))
      | 'Transform record' >> beam.Map(transform_record)
      | 'Write to BQ' >> beam.ParDo(WritePlanDataToBigQuery(custom_options.year))
    )

if __name__ == '__main__':
  run()
</code>```

```<code>class CustomOptions(PipelineOptions):
  @classmethod
  def _add_argparse_args(cls, parser):
    parser.add_value_provider_argument('--year', type=int)
    parser.add_value_provider_argument('--secret_name', type=str)
</code>```

```<code>class WritePlanDataToBigQuery(beam.DoFn):
  def __init__(self, year_vp):
    self._year_vp = year_vp

  def process(self, element):
    year = self._year_vp.get()

    table = f's4c.plan_data_{year}'
    schema = {
      'fields': [ ...some fields properties ]
    }

    beam.io.WriteToBigQuery(
      table=table,
      schema=schema,
      create_disposition=BigQueryDisposition.CREATE_IF_NEEDED,
      write_disposition=BigQueryDisposition.WRITE_TRUNCATE,
      method=beam.io.WriteToBigQuery.Method.FILE_LOADS
    )
</code>```

答:
You have instantiated the PTransform beam.io.gcp.bigquery.WriteToBigQuery inside the process method of your DoFn. There are a couple of problems here:

The process method is called for each element of the input PCollection. It is not used for building the pipeline graph. This approach to dynamically constructing the graph will not work.

Once you move it out of the DoFn, you need to apply the PTransform beam.io.gcp.bigquery.WriteToBigQuery to a PCollection for it to have any effect. See the Beam pydoc or the Beam tutorial documentation.

To create a derived value provider for your table name, you would need a "nested" value provider. Unfortunately this is not supported for the Python SDK. You can use the value provider option directly, though.

As an advanced option, you may be interested in trying out "flex templates" which essentially package up your whole program as a docker image and execute it with parameters.

Body:
I've created a dataflow template with some parameters. When I write the data to BigQuery, I would like to make use of these parameters to determine which table it is supposed to write to. I've tried calling WriteToBigQuery in a ParDo as  suggested in the following link.

How can I write to Big Query using a runtime value provider in Apache Beam?

The pipeline ran successfully but it is not creating or loading data to BigQuery. Any idea what might be the issue?

def run():
  pipeline_options = PipelineOptions()
  pipeline_options.view_as(DebugOptions).experiments = ['use_beam_bq_sink']

  with beam.Pipeline(options=pipeline_options) as p:
    custom_options = pipeline_options.view_as(CustomOptions)

    _ = (
      p
      | beam.Create([None])
      | 'Year to periods' >> beam.ParDo(SplitYearToPeriod(custom_options.year))
      | 'Read plan data' >> beam.ParDo(GetPlanDataByPeriod(custom_options.secret_name))
      | 'Transform record' >> beam.Map(transform_record)
      | 'Write to BQ' >> beam.ParDo(WritePlanDataToBigQuery(custom_options.year))
    )

if __name__ == '__main__':
  run()

class CustomOptions(PipelineOptions):
  @classmethod
  def _add_argparse_args(cls, parser):
    parser.add_value_provider_argument('--year', type=int)
    parser.add_value_provider_argument('--secret_name', type=str)

class WritePlanDataToBigQuery(beam.DoFn):
  def __init__(self, year_vp):
    self._year_vp = year_vp

  def process(self, element):
    year = self._year_vp.get()

    table = f's4c.plan_data_{year}'
    schema = {
      'fields': [ ...some fields properties ]
    }

    beam.io.WriteToBigQuery(
      table=table,
      schema=schema,
      create_disposition=BigQueryDisposition.CREATE_IF_NEEDED,
      write_disposition=BigQueryDisposition.WRITE_TRUNCATE,
      method=beam.io.WriteToBigQuery.Method.FILE_LOADS
    )


问:
Error while creating Google Drive folder into another folder
I need create GDrive folder into another GDrive folder.

There's the code:

```<code>private static String createDriveFolder(String folderName, String mainFolder, Drive service) throws IOException {
    File fileMetadata = new File();
    fileMetadata.setName(folderName);
    fileMetadata.setParents(Collections.singletonList(mainFolder));
    fileMetadata.setMimeType("application/vnd.google-apps.folder");

    File file = service.files().create(fileMetadata)
            .setFields("id, parent")
            .execute();
    System.out.println("Folder ID: " + file.getId());
    return file.getId();
}
</code>```

I get this error...

```<code>Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "location" : "fields",
    "locationType" : "parameter",
    "message" : "Invalid field selection parent",
    "reason" : "invalidParameter"
  } ],
  "message" : "Invalid field selection parent"
}
</code>```

Please help me...

答:
How about this modification? I think that from the error message, the reason of the issue is due to the value of fields.

From:

```<code>.setFields("id, parent")
</code>```

To:

```<code>.setFields("id, parents")
</code>```

Note:

Please modify parent to parents. At Google Drive, in the current stage, a file and folder have the multiple parents. So parents is used. But we can see the following announce. Ref

Beginning Sept. 30, 2020, it will no longer be possible to place an item in multiple folders; every item will have exactly one location. In the new model, shortcuts can be used to organize content in multiple hierarchies. This simplification of Drive's folder structure and sharing models will result in a change in the way some Google Drive API endpoints behave.

I'm not sure whether parents will be changed to parent. So about this, I would like to confirm the change of the Drive API after Sept. 30, 2020.

Reference:

Files

Body:
I need create GDrive folder into another GDrive folder.

There's the code:

private static String createDriveFolder(String folderName, String mainFolder, Drive service) throws IOException {
    File fileMetadata = new File();
    fileMetadata.setName(folderName);
    fileMetadata.setParents(Collections.singletonList(mainFolder));
    fileMetadata.setMimeType("application/vnd.google-apps.folder");

    File file = service.files().create(fileMetadata)
            .setFields("id, parent")
            .execute();
    System.out.println("Folder ID: " + file.getId());
    return file.getId();
}

I get this error...

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "location" : "fields",
    "locationType" : "parameter",
    "message" : "Invalid field selection parent",
    "reason" : "invalidParameter"
  } ],
  "message" : "Invalid field selection parent"
}

Please help me...

Body:
How about this modification? I think that from the error message, the reason of the issue is due to the value of fields.

From:

.setFields("id, parent")

To:

.setFields("id, parents")

Note:

Please modify parent to parents. At Google Drive, in the current stage, a file and folder have the multiple parents. So parents is used. But we can see the following announce. Ref

Beginning Sept. 30, 2020, it will no longer be possible to place an item in multiple folders; every item will have exactly one location. In the new model, shortcuts can be used to organize content in multiple hierarchies. This simplification of Drive's folder structure and sharing models will result in a change in the way some Google Drive API endpoints behave.

I'm not sure whether parents will be changed to parent. So about this, I would like to confirm the change of the Drive API after Sept. 30, 2020.

Reference:

Files