问:
How to have a Manifest-declared broadcast receiver communicate with an activity or service?
This should be obvious but I can't find the solution. Many people have asked it and the reply is usually to just switch to a context-registered receiver instead. I have an accessibility service which needs to be notified when the Manifest-declared receiver picks up something. Obviously this can't be done with an interface since I can't find a way to get the instance of the receiver. Here's some code:

Manifest:

```<code><service
    android:name=".MyAccessibilityService"
    android:exported="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>

    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibilityservice" />
</service>

<receiver
    android:name=".MyBroadcastReceiver"
    android:exported="false"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="roastie_toastie" />
    </intent-filter>
</receiver>
</code>```

Receiver:

```<code>public class MyBroadcastReceiver extends BroadcastReceiver {
    BroadcastReceivedListener mBroadcastReceivedListener;

    public void setBroadcastReceivedListener(BroadcastReceivedListener broadcastReceivedListener) {
        mBroadcastReceivedListener = broadcastReceivedListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        mBroadcastReceivedListener.broadcastReceived();
    }

    public interface BroadcastReceivedListener {
        void broadcastReceived();
    }
}
</code>```

MyAccessibilityService:

```<code>public class MyAccessibilityService extends AccessibilityService implements MyBroadcastReceiver.BroadcastReceivedListener {

    boolean lightsAreOn = true;

    @Override
    public void broadcastReceived() {
        lightsAreOn = false;
    }
}
</code>```

答:
I asked a couple of times for concrete scenarios, and you did not really provide any, so I am going to answer with an abstract scenario: suppose that your broadcast is designed to send a command to the service.

In that case, you could:

Implement a singleton (here called CommandBus, for lack of a better idea of a name). Ideally, that singleton would be set up by a dependency inversion framework (e.g., Dagger/Hilt).

Have CommandBus expose some reactive way to get commands to the service. If you were using Kotlin, that could be a SharedFlow. Since you are using Java, that could be an RxJava Observable, or perhaps a simple callback.

Have MyAccessibilityService get access to the CommandBus singleton and use whatever you set up in step #2 to find out about commands.

Have CommandBus expose an API to hand it commands to deliver to the service (e.g., a sendCommand() method).

Have MyBroadcastReceiver get access to the CommandBus singleton and call the method from step #4 in onReceive().

At this point, when MyBroadcastReceiver receives a broadcast, it tells CommandBus to send the command, which then flows over to MyAccessibilityService, which goes and does something.

Body:
This should be obvious but I can't find the solution. Many people have asked it and the reply is usually to just switch to a context-registered receiver instead. I have an accessibility service which needs to be notified when the Manifest-declared receiver picks up something. Obviously this can't be done with an interface since I can't find a way to get the instance of the receiver. Here's some code:

Manifest:

<service
    android:name=".MyAccessibilityService"
    android:exported="true"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>

    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibilityservice" />
</service>

<receiver
    android:name=".MyBroadcastReceiver"
    android:exported="false"
    android:process=":listenerProcess4">
    <intent-filter>
        <action android:name="roastie_toastie" />
    </intent-filter>
</receiver>

Receiver:

public class MyBroadcastReceiver extends BroadcastReceiver {
    BroadcastReceivedListener mBroadcastReceivedListener;

    public void setBroadcastReceivedListener(BroadcastReceivedListener broadcastReceivedListener) {
        mBroadcastReceivedListener = broadcastReceivedListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        mBroadcastReceivedListener.broadcastReceived();
    }

    public interface BroadcastReceivedListener {
        void broadcastReceived();
    }
}

MyAccessibilityService:

public class MyAccessibilityService extends AccessibilityService implements MyBroadcastReceiver.BroadcastReceivedListener {

    boolean lightsAreOn = true;

    @Override
    public void broadcastReceived() {
        lightsAreOn = false;
    }
}


来源: stackexchange

问:
How to force looplifting in Numba?
I'm trying to implement a Numba-compiled version of numpy.take(), but I'm very confused by Numba.

Firstly, as I understand it's not possible to create a new ndarray inside a numba function in nopython mode. Current version of the docs doesn't seem to mention it anywhere, but I was able to find it in old Numba v0.15 docs. So I have to abandon nopython mode.

Secondly, I don't understand how looplifting works, at least with my tests. Here is my code:

```<code>from numba import jit
import numpy as np
import time

@jit(forceobj = True)
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res

def _take2(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res

sz = 2000000
arr = np.arange(sz, dtype = np.int32)
idxs = np.arange(sz, 0, -1, dtype = np.int32)

start = time.time()
_take2(arr, idxs)
end = time.time()
print("Elapsed (plain python)      = %s" % (end - start))

start = time.time()
_take1(arr, idxs)
end = time.time()
print("Elapsed (with compilation)  = %s" % (end - start))

start = time.time()
_take1(arr, idxs)
end = time.time()
print("Elapsed (after compilation) = %s" % (end - start))
</code>```

This code gives the following output on my laptop:

```<code>Elapsed (plain python)      = 0.8870017528533936
Elapsed (with compilation)  = 1.7350387573242188
Elapsed (after compilation) = 1.1779978275299072
</code>```

So the compiled version is slower than pure python. My guess is that it's because it doesn't use "looplifting" and I can't find a way to enable it. On the other hand, the 5-minute guide states about the object mode:

In this mode Numba will identify loops that it can compile and compile those into functions that run in machine code, and it will run the rest of the code in the interpreter

But there is a catch. If I remove (forceobj = True) from the 5th line (leaving just @jit) I get the following output:

```<code>Elapsed (plain python)      = 0.88104248046875
c:\[path-to-my-folder]\test.py:6: NumbaWarning:
Compilation is falling back to object mode WITH looplifting enabled because Function "_take1" failed type inference due to: Use of unsupported NumPy function 'numpy.ndarray' or unsupported use of the function.

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^

During: typing of get attribute at c:\[path-to-my-folder]\test.py (8)

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^

  @jit

  warnings.warn(errors.NumbaWarning(warn_msg,
C:\[path-to-my-python]\python38\lib\site-packages\numba\core\object_mode_passes.py:161: NumbaDeprecationWarning:
Fall-back from the nopython compilation path to the object mode compilation path has been detected, this is deprecated behaviour.

For more information visit https://numba.pydata.org/numba-doc/latest/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^
  warnings.warn(errors.NumbaDeprecationWarning(msg,
Elapsed (with compilation)  = 0.4593193531036377
Elapsed (after compilation) = 0.0029413700103759766
</code>```

So now the compiled version of the function is drastically faster than pure python even though numba is still clearly in object mode. What is suspicious to me is object mode WITH looplifting enabled in the warning text. It looks like there could also be an object mode without looplifting.

To summarize, I have 3 questions:

Is it true that I can not create a new ndarray with Numba in nopython mode?

Why does @jit with fallback to object mode works a lot faster than @jit(forceobj = True)?

Is there an object mode without looplifting in Numba? And if so, what is its purpose?

Thank you!

答:
Is it true that I can not create a new ndarray with Numba in nopython mode?

This is wrong. The following working code does that:

import numpy as np
import numba as nb

@nb.njit('int32[:](int32)')
def example(n):
    res = np.empty(n, dtype=np.int32)
    for i in range(n):
        res[i] = i
    return res

example(4)  # output: [0, 1, 2, 3]
```
<blockquote>
<p>Why does @jit with fallback to object mode works a lot faster than @jit(forceobj = True)?</p>
</blockquote>
<p>You should <strong>avoid the object mode like the plague</strong>. It is generally very inefficient and often not really useful unless you deals with Python objects which are slow to compute due to the GIL, reference counting, allocations, dynamic-typing and many performance issues that makes CPython slow. The documentation states:</p>
<blockquote>
<p>Whilst the use of looplifting in object mode can enable some performance increase, getting functions to compile under <strong>no python mode</strong> is really the key to good performance.</p>
</blockquote>
<p>Moreover, it also states:</p>
<blockquote>
<p><code>forceobj</code> forces the function to be compiled in object mode. Since object mode is slower than nopython mode, this is mostly useful for testing purposes.</p>
</blockquote>
<p>Thus, the challenge is to make your code build with the <code>njit</code> mode. In your case this is simple: you just need to use <code>np.empty</code> and <code>njit</code>.</p>
<pre class="lang-py prettyprint-override"><code>@njit
def _take1(arr, idxs):
    res = np.empty((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res
</code>```

This make the code much master on my machine:

Elapsed (plain python)      = 3.343827962875366
Elapsed (with compilation)  = 0.06859207153320312
Elapsed (after compilation) = 0.00159454345703125
```

Note that you can provide the signature of _take1 so Numba can compile it eagerly.

Is there an object mode without looplifting in Numba? And if so, what is its purpose?

The purpose of the object mode is simply the compatibility with pure-Python code. This is useful when a Numba code is mixed with pure-Python functions. The pure-Python function call will be slow but at least Numba can call them in the middle of a Numba code. The object mode is often not very useful in optimized Numba codes, and if you use it, then you generally need the looplifting so to boost the performance of hot loops. Otherwise, using Numba is certainly not very useful in the target case (rare exceptions include wrapping codes).

ContentLicense: CC BY-SA 4.0

Title: How to force looplifting in Numba?

Body:
I'm trying to implement a Numba-compiled version of numpy.take(), but I'm very confused by Numba.

Firstly, as I understand it's not possible to create a new ndarray inside a numba function in nopython mode. Current version of the docs doesn't seem to mention it anywhere, but I was able to find it in old Numba v0.15 docs. So I have to abandon nopython mode.

Secondly, I don't understand how looplifting works, at least with my tests. Here is my code:

from numba import jit
import numpy as np
import time

@jit(forceobj = True)
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res

def _take2(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res

sz = 2000000
arr = np.arange(sz, dtype = np.int32)
idxs = np.arange(sz, 0, -1, dtype = np.int32)

start = time.time()
_take2(arr, idxs)
end = time.time()
print("Elapsed (plain python)      = %s" % (end - start))

start = time.time()
_take1(arr, idxs)
end = time.time()
print("Elapsed (with compilation)  = %s" % (end - start))

start = time.time()
_take1(arr, idxs)
end = time.time()
print("Elapsed (after compilation) = %s" % (end - start))

This code gives the following output on my laptop:

Elapsed (plain python)      = 0.8870017528533936
Elapsed (with compilation)  = 1.7350387573242188
Elapsed (after compilation) = 1.1779978275299072

So the compiled version is slower than pure python. My guess is that it's because it doesn't use "looplifting" and I can't find a way to enable it. On the other hand, the 5-minute guide states about the object mode:

In this mode Numba will identify loops that it can compile and compile those into functions that run in machine code, and it will run the rest of the code in the interpreter

But there is a catch. If I remove (forceobj = True) from the 5th line (leaving just @jit) I get the following output:

Elapsed (plain python)      = 0.88104248046875
c:\[path-to-my-folder]\test.py:6: NumbaWarning:
Compilation is falling back to object mode WITH looplifting enabled because Function "_take1" failed type inference due to: Use of unsupported NumPy function 'numpy.ndarray' or unsupported use of the function.

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^

During: typing of get attribute at c:\[path-to-my-folder]\test.py (8)

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^

  @jit

  warnings.warn(errors.NumbaWarning(warn_msg,
C:\[path-to-my-python]\python38\lib\site-packages\numba\core\object_mode_passes.py:161: NumbaDeprecationWarning:
Fall-back from the nopython compilation path to the object mode compilation path has been detected, this is deprecated behaviour.

For more information visit https://numba.pydata.org/numba-doc/latest/reference/deprecation.html#deprecation-of-object-mode-fall-back-behaviour-when-using-jit

File "test.py", line 8:
def _take1(arr, idxs):
    res = np.ndarray((idxs.size,), arr.dtype)
    ^
  warnings.warn(errors.NumbaDeprecationWarning(msg,
Elapsed (with compilation)  = 0.4593193531036377
Elapsed (after compilation) = 0.0029413700103759766

So now the compiled version of the function is drastically faster than pure python even though numba is still clearly in object mode. What is suspicious to me is object mode WITH looplifting enabled in the warning text. It looks like there could also be an object mode without looplifting.

To summarize, I have 3 questions:

Is it true that I can not create a new ndarray with Numba in nopython mode?

Why does @jit with fallback to object mode works a lot faster than @jit(forceobj = True)?

Is there an object mode without looplifting in Numba? And if so, what is its purpose?

Thank you!

Body:
Is it true that I can not create a new ndarray with Numba in nopython mode?

This is wrong. The following working code does that:

import numpy as np
import numba as nb

@nb.njit('int32[:](int32)')
def example(n):
    res = np.empty(n, dtype=np.int32)
    for i in range(n):
        res[i] = i
    return res

example(4)  # output: [0, 1, 2, 3]

Why does @jit with fallback to object mode works a lot faster than @jit(forceobj = True)?

You should avoid the object mode like the plague. It is generally very inefficient and often not really useful unless you deals with Python objects which are slow to compute due to the GIL, reference counting, allocations, dynamic-typing and many performance issues that makes CPython slow. The documentation states:

Whilst the use of looplifting in object mode can enable some performance increase, getting functions to compile under no python mode is really the key to good performance.

Moreover, it also states:

forceobj forces the function to be compiled in object mode. Since object mode is slower than nopython mode, this is mostly useful for testing purposes.

Thus, the challenge is to make your code build with the njit mode. In your case this is simple: you just need to use np.empty and njit.

@njit
def _take1(arr, idxs):
    res = np.empty((idxs.size,), arr.dtype)
    lastIdx = arr.size - 1
    for i in range(idxs.size):
        idx = idxs[i]
        if idx > lastIdx:
            idx = lastIdx
        elif idx < 0:
            idx = 0
        res[i] = arr[idx]
    return res

This make the code much master on my machine:

Elapsed (plain python)      = 3.343827962875366
Elapsed (with compilation)  = 0.06859207153320312
Elapsed (after compilation) = 0.00159454345703125

Note that you can provide the signature of _take1 so Numba can compile it eagerly.

Is there an object mode without looplifting in Numba? And if so, what is its purpose?

The purpose of the object mode is simply the compatibility with pure-Python code. This is useful when a Numba code is mixed with pure-Python functions. The pure-Python function call will be slow but at least Numba can call them in the middle of a Numba code. The object mode is often not very useful in optimized Numba codes, and if you use it, then you generally need the looplifting so to boost the performance of hot loops. Otherwise, using Numba is certainly not very useful in the target case (rare exceptions include wrapping codes).


问:
Nested validation with the flask-restful RequestParser
Using the flask-restful micro-framework, I am having trouble constructing a RequestParser that will validate nested resources.  Assuming an expected JSON resource format of the form:

```<code>{
    'a_list': [
        {
            'obj1': 1,
            'obj2': 2,
            'obj3': 3
        },
        {
            'obj1': 1,
            'obj2': 2,
            'obj3': 3
        }
    ]
}
</code>```

Each item in a_list corresponds to an object:

```<code>class MyObject(object):
    def __init__(self, obj1, obj2, obj3)
        self.obj1 = obj1
        self.obj2 = obj2
        self.obj3 = obj3
</code>```

... and one would then create a RequestParser using a form something like:

```<code>from flask.ext.restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('a_list', type=MyObject, action='append')
</code>```

... but how would you validate the nested MyObjects of each dictionary inside a_list?  Or, alternately, is this the wrong approach?

The API this corresponds to treats each MyObject as, essentially, an object literal, and there may be one or more of them passed to the service; therefore, flattening the resource format will not work for this circumstance.

答:
```<code>import jsonschema
from jsonschema import validate

def validate_json_request(jsonData, schema):
    try:
        validate(instance=jsonData, schema=schema)
    except jsonschema.exceptions.ValidationError as err:
        return False
    return True

@api.resource('/product-catalog-api/accounts/<string:domain>/selected/list', endpoint='product-list-varient-resolver-apis')
class ProductVarientRealAPI(Resource):
    def __init__(self) -> None:
        '''
            {
                "products": [
                    {
                        "baseCode": "cEMbseQRA-fJGo-YD2ggc_base00",
                        "selectedVarientList": [
                            "Hoe60Ypbxzxd0aMRmV4Ff",
                            "gMVWwbxfPSyaXQjRLX4Sv"
                        ]
                    },
                    {
                        "baseCode": "cEMbseQRA-fJGo-YD2ggc_base00",
                        "selectedVarientList": [
                            "UzsdFS7ZgFPTUnwswVpuq",
                            "gMVWwbxfPSyaXQjRLX4Sv"
                        ]
                    }
                ]
            }
        '''

        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument(
            'products', required=True, type=dict, help="need [products]", action="append")

    def post(self, domain):
        products_schema = {
            'type': 'array',
            'items': {
                'type': 'object',
                'properties': {
                    'baseCode': {
                        'type': 'string',
                    },
                    'selectedVarientList': {
                        'type': 'array',
                        'items': {'type':'string'}
                    }
                }
            }
        }

        try:
            args = self.reqparse.parse_args()
            if not validate_json_request(args.products, products_schema): # check like this
                raise Exception("Invalid Data")
            product_list = []
            for product in args.products:
                product_info, status = get_product_varient(product["baseCode"], domain, product["selectedVarientList"])
                if status == 200:
                    product_list.append(product_info)
            return {
                'api_response_info': {
                    'message': 'Fetched Product Varients',
                },
                'data': product_list
            }, 200
        except Exception as err:
            print("error occ", err)
            return {
                'message': 'Error: {}'.format(err)
            }, 500
</code>```

i tried above methods, in the posts this is more readable and better i
think, it gives you a better abstraction layer. but here is 2 type of
validations going which might make this req slow. one is regparser
which is slow, and jsonschema is also slow**

ContentLicense: CC BY-SA 3.0

Body:
Using the flask-restful micro-framework, I am having trouble constructing a RequestParser that will validate nested resources.  Assuming an expected JSON resource format of the form:

{
    'a_list': [
        {
            'obj1': 1,
            'obj2': 2,
            'obj3': 3
        },
        {
            'obj1': 1,
            'obj2': 2,
            'obj3': 3
        }
    ]
}

Each item in a_list corresponds to an object:

class MyObject(object):
    def __init__(self, obj1, obj2, obj3)
        self.obj1 = obj1
        self.obj2 = obj2
        self.obj3 = obj3

... and one would then create a RequestParser using a form something like:

from flask.ext.restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('a_list', type=MyObject, action='append')

... but how would you validate the nested MyObjects of each dictionary inside a_list?  Or, alternately, is this the wrong approach?

The API this corresponds to treats each MyObject as, essentially, an object literal, and there may be one or more of them passed to the service; therefore, flattening the resource format will not work for this circumstance.

Body:
import jsonschema
from jsonschema import validate

def validate_json_request(jsonData, schema):
    try:
        validate(instance=jsonData, schema=schema)
    except jsonschema.exceptions.ValidationError as err:
        return False
    return True

@api.resource('/product-catalog-api/accounts/<string:domain>/selected/list', endpoint='product-list-varient-resolver-apis')
class ProductVarientRealAPI(Resource):
    def __init__(self) -> None:
        '''
            {
                "products": [
                    {
                        "baseCode": "cEMbseQRA-fJGo-YD2ggc_base00",
                        "selectedVarientList": [
                            "Hoe60Ypbxzxd0aMRmV4Ff",
                            "gMVWwbxfPSyaXQjRLX4Sv"
                        ]
                    },
                    {
                        "baseCode": "cEMbseQRA-fJGo-YD2ggc_base00",
                        "selectedVarientList": [
                            "UzsdFS7ZgFPTUnwswVpuq",
                            "gMVWwbxfPSyaXQjRLX4Sv"
                        ]
                    }
                ]
            }
        '''

        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument(
            'products', required=True, type=dict, help="need [products]", action="append")

    def post(self, domain):
        products_schema = {
            'type': 'array',
            'items': {
                'type': 'object',
                'properties': {
                    'baseCode': {
                        'type': 'string',
                    },
                    'selectedVarientList': {
                        'type': 'array',
                        'items': {'type':'string'}
                    }
                }
            }
        }

        try:
            args = self.reqparse.parse_args()
            if not validate_json_request(args.products, products_schema): # check like this
                raise Exception("Invalid Data")
            product_list = []
            for product in args.products:
                product_info, status = get_product_varient(product["baseCode"], domain, product["selectedVarientList"])
                if status == 200:
                    product_list.append(product_info)
            return {
                'api_response_info': {
                    'message': 'Fetched Product Varients',
                },
                'data': product_list
            }, 200
        except Exception as err:
            print("error occ", err)
            return {
                'message': 'Error: {}'.format(err)
            }, 500

i tried above methods, in the posts this is more readable and better i
think, it gives you a better abstraction layer. but here is 2 type of
validations going which might make this req slow. one is regparser
which is slow, and jsonschema is also slow**


问:
why the style scope make Error: TypeScript emitted no output error
When I added scoped in the vue 3 component style block like this:

```<code><style lang="scss" scoped>

#translate-btn {
    //display: none;
    position: absolute;
    z-index: 9999999999;
    left: 0;
    top: 0;
}

#translate-btn .reddwarf-btn-icon{
  width: 18px;
  height: 28px;
  background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
  background-color: transparent;

}

.translate-pop-button{
  width: 28px;
  height: 28px;
  background:transparent;
  background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
  background-color:transparent;
}

</style>
</code>```

shows compile error:

```<code>ERROR in ./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true (./node_modules/ts-loader/index.js??clonedRuleSet-1!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[11].use[0]!./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true)
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for /Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/src/public/widget/translator/TranslatorPop.vue.ts.
    at makeSourceMapAndFinish (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:52:18)
    at successLoader (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:39:5)
    at Object.loader (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:22:5)
 @ ./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true 1:0-307 1:0-307
 @ ./src/public/widget/translator/TranslatorPop.vue 1:0-94 8:68-74
 @ ./src/content/handler/PageEvent.ts 1:0-73 44:30-43
 @ ./src/content/index.ts 1:0-79 4:36-48 7:8-26

webpack 5.67.0 compiled with 1 error in 124 ms
</code>```

why the scoped limit cause the error? when I removed the scoped, the compiler works fine, when added the scope, the compiler build faild and shows the error.This is the webpack config:

```<code>  const path = require('path');
  const webpack = require( 'webpack' );
  const MiniCssExtractPlugin = require( 'mini-css-extract-plugin');
  const HtmlWebpackPlugin = require( 'html-webpack-plugin');
  const CopyPlugin = require("copy-webpack-plugin");
  const { VueLoaderPlugin } = require("vue-loader");

  module.exports = {
    entry : {
      'popup/popup' : './src/popup/',
      'background/background': './src/background',
      'content/content': './src/content'
    } ,
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
      alias: {
          vue: 'vue/dist/vue.esm-bundler.js',
          process: 'process/browser',
          '@': path.resolve(__dirname, '../../../src'),
      },
    },
    output : {
      path : path.resolve(__dirname, '../../bundle') ,
      filename : '[name].js'
    },
    module : {
      rules : [
        {
          test: /\.ts$/,
          loader: 'ts-loader',
          options: {
            appendTsSuffixTo: [/\.vue$/]
          },
          exclude: /node_modules|\.d\.ts$/
        },
        {
          test: /\.d\.ts$/,
          loader: 'ignore-loader'
        },
        {
          test: /\.vue$/,
          loader: 'vue-loader'
        },
        {
          test : /\.js$/ ,
          exclude : [ /node_modules(?!(\/|\\?\\)(translation\.js|selection-widget|connect\.io|chrome-env)\1)/ ] ,
          loader : 'babel-loader'
        } ,
        {
          test: /\.css$/i,
          use: [MiniCssExtractPlugin.loader, "css-loader"],
        },
        {
          test : /\.(scss)$/ ,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }
      ]
    },
    plugins : [
      new webpack.ProvidePlugin({
        process: 'process/browser',
      }),
      new VueLoaderPlugin(),
      new CopyPlugin({
        patterns: [
          { from: "src/manifest.json", to: "manifest.json" },
          { from: "src/resource/image", to: "resource/image" },
        ],
      }),
      new MiniCssExtractPlugin({
        filename: "[name].css",
        chunkFilename: "[id].css",
      }),
      new HtmlWebpackPlugin({
        filename: 'popup/popup.html',
        template: 'src/popup/index.html',
        inject: false,
      }),
      new webpack.DefinePlugin({
        __VUE_OPTIONS_API__: false,
        __VUE_PROD_DEVTOOLS__: false,
      }),
    ]
  };
</code>```

答:
Have you tried removing the lang="scss" attribute, you are using regular nesting in your css code and maybe that's causing the problem with the scss syntax.

I tried the following and worked fine. However, it is probably very different from your original code.

```<code><template>
    <div>
        <button id="translate-btn">
            <i class="reddwarf-btn-icon"></i><span>Lorem, ipsum.</span>
        </button>
        <div class="translate-pop-button"></div>
    </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
    name : 'Test'
})
</script>

<style scoped>
#translate-btn {
    /*display: none;*/
    position: absolute;
    z-index: 9999999999;
    left: 0;
    top: 0;
}
#translate-btn .reddwarf-btn-icon{
    width: 18px;
    height: 28px;
    background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
    background-color: transparent;
}

.translate-pop-button{
  width: 28px;
  height: 28px;
  background:transparent;
  background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
  background-color:transparent;
}
</style>
</code>```

Body:
When I added scoped in the vue 3 component style block like this:

shows compile error:

ERROR in ./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true (./node_modules/ts-loader/index.js??clonedRuleSet-1!./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[3]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[11].use[0]!./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true)
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for /Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/src/public/widget/translator/TranslatorPop.vue.ts.
    at makeSourceMapAndFinish (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:52:18)
    at successLoader (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:39:5)
    at Object.loader (/Users/xiaoqiangjiang/source/reddwarf/frontend/reddwarf-translate-plugin/node_modules/ts-loader/dist/index.js:22:5)
 @ ./src/public/widget/translator/TranslatorPop.vue?vue&type=template&id=6bc385e0&scoped=true&ts=true 1:0-307 1:0-307
 @ ./src/public/widget/translator/TranslatorPop.vue 1:0-94 8:68-74
 @ ./src/content/handler/PageEvent.ts 1:0-73 44:30-43
 @ ./src/content/index.ts 1:0-79 4:36-48 7:8-26

webpack 5.67.0 compiled with 1 error in 124 ms

why the scoped limit cause the error? when I removed the scoped, the compiler works fine, when added the scope, the compiler build faild and shows the error.This is the webpack config:

  const path = require('path');
  const webpack = require( 'webpack' );
  const MiniCssExtractPlugin = require( 'mini-css-extract-plugin');
  const HtmlWebpackPlugin = require( 'html-webpack-plugin');
  const CopyPlugin = require("copy-webpack-plugin");
  const { VueLoaderPlugin } = require("vue-loader");

  module.exports = {
    entry : {
      'popup/popup' : './src/popup/',
      'background/background': './src/background',
      'content/content': './src/content'
    } ,
    resolve: {
      extensions: ['.tsx', '.ts', '.js'],
      alias: {
          vue: 'vue/dist/vue.esm-bundler.js',
          process: 'process/browser',
          '@': path.resolve(__dirname, '../../../src'),
      },
    },
    output : {
      path : path.resolve(__dirname, '../../bundle') ,
      filename : '[name].js'
    },
    module : {
      rules : [
        {
          test: /\.ts$/,
          loader: 'ts-loader',
          options: {
            appendTsSuffixTo: [/\.vue$/]
          },
          exclude: /node_modules|\.d\.ts$/
        },
        {
          test: /\.d\.ts$/,
          loader: 'ignore-loader'
        },
        {
          test: /\.vue$/,
          loader: 'vue-loader'
        },
        {
          test : /\.js$/ ,
          exclude : [ /node_modules(?!(\/|\\?\\)(translation\.js|selection-widget|connect\.io|chrome-env)\1)/ ] ,
          loader : 'babel-loader'
        } ,
        {
          test: /\.css$/i,
          use: [MiniCssExtractPlugin.loader, "css-loader"],
        },
        {
          test : /\.(scss)$/ ,
          use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
        }
      ]
    },
    plugins : [
      new webpack.ProvidePlugin({
        process: 'process/browser',
      }),
      new VueLoaderPlugin(),
      new CopyPlugin({
        patterns: [
          { from: "src/manifest.json", to: "manifest.json" },
          { from: "src/resource/image", to: "resource/image" },
        ],
      }),
      new MiniCssExtractPlugin({
        filename: "[name].css",
        chunkFilename: "[id].css",
      }),
      new HtmlWebpackPlugin({
        filename: 'popup/popup.html',
        template: 'src/popup/index.html',
        inject: false,
      }),
      new webpack.DefinePlugin({
        __VUE_OPTIONS_API__: false,
        __VUE_PROD_DEVTOOLS__: false,
      }),
    ]
  };

Body:
Have you tried removing the lang="scss" attribute, you are using regular nesting in your css code and maybe that's causing the problem with the scss syntax.

I tried the following and worked fine. However, it is probably very different from your original code.

<template>
    <div>
        <button id="translate-btn">
            <i class="reddwarf-btn-icon"></i><span>Lorem, ipsum.</span>
        </button>
        <div class="translate-pop-button"></div>
    </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
    name : 'Test'
})
</script>

<style scoped>
#translate-btn {
    /*display: none;*/
    position: absolute;
    z-index: 9999999999;
    left: 0;
    top: 0;
}
#translate-btn .reddwarf-btn-icon{
    width: 18px;
    height: 28px;
    background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
    background-color: transparent;
}

.translate-pop-button{
  width: 28px;
  height: 28px;
  background:transparent;
  background-image: url('chrome-extension://__MSG_@@extension_id__/resource/image/lo.jpg');
  background-color:transparent;
}
</style>


问:
PytzUsageWarning: The zone attribute is specific to pytz's interface; please migrate to a new time zone provider
I am writing a simple function that sends messages based on a schedule using AsyncIOScheduler.

```<code>scheduler = AsyncIOScheduler()
scheduler.add_job(job, "cron", day_of_week="mon-fri", hour = "16")
scheduler.start()
</code>```

It seems to work, but I always get the following message:

```<code>PytzUsageWarning: The zone attribute is specific to pytz's interface; please migrate to a new time zone provider. For more details on how to do so, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
PytzUsageWarning: The localize method is no longer necessary, as this time zone supports the fold attribute (PEP 495)
</code>```

I am not familiar with time in python at all, so I am not really sure what this message is asking me to do. I visited the link provided in the message, but the explanation there is too complicated for me. As I understand, I have to migrate to using PEP495, but how exactly can I do just that?

答:
I just changed to</p>
```<code>if __name__ == '__main__':
scheduler = BlockingScheduler(timezone=pytz.timezone('Asia/Ho_Chi_Minh'))
</code>```

Body:
I am writing a simple function that sends messages based on a schedule using AsyncIOScheduler.

scheduler = AsyncIOScheduler()
scheduler.add_job(job, "cron", day_of_week="mon-fri", hour = "16")
scheduler.start()

It seems to work, but I always get the following message:

PytzUsageWarning: The zone attribute is specific to pytz's interface; please migrate to a new time zone provider. For more details on how to do so, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
PytzUsageWarning: The localize method is no longer necessary, as this time zone supports the fold attribute (PEP 495)

I am not familiar with time in python at all, so I am not really sure what this message is asking me to do. I visited the link provided in the message, but the explanation there is too complicated for me. As I understand, I have to migrate to using PEP495, but how exactly can I do just that?

Body:
I just changed to

if __name__ == '__main__':
scheduler = BlockingScheduler(timezone=pytz.timezone('Asia/Ho_Chi_Minh'))


问:
how do I call my functions in .net
I am learning .net and writing a service by following the tutorial below http://www.beansoftware.com/NET-Tutorials/Create-Windows-Services.aspx

The windows service gets installed successfully and it starts too. But when I change the file name or delete a file or add a file, it doesnt add any information to my log file which is in
C:\Folder\FolderLog.txt

I see 3 methods for FolderWatcher_** but I dont see a call to those in the code. I am very new to .net so I am not sure how they are being called

here is my complete code

```<code>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;

    namespace Watcher
    {
        public partial class Watcher : ServiceBase
        {
            public Watcher()
            {
                InitializeComponent();
            }

            protected override void OnStart(string[] args)
            {

            }

            protected override void OnStop()
            {
            }

            private void FolderWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\FolderLog.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been created. ");
                writer.Close();
            }

            private void FolderWatcher_Deleted(object sender, System.IO.FileSystemEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\FolderLog.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been deleted. ");
                writer.Close();
            }

            private void FolderWatcher_Renamed(object sender, System.IO.RenamedEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\log.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been renamed. ");
                writer.Close();
            }

        }
    }
</code>```

I have followed every single step in that tutorial. I have not seen anything that descibes how these methods are called. Any help would be great

答: The tutorial probably has you adding a FileSystemWatcher in the design mode surface for your service.  In design mode, select that object and in its event handlers, select the appropriate methods of your class.

Title: how do I call my functions in .net

Body:
I am learning .net and writing a service by following the tutorial below http://www.beansoftware.com/NET-Tutorials/Create-Windows-Services.aspx

The windows service gets installed successfully and it starts too. But when I change the file name or delete a file or add a file, it doesnt add any information to my log file which is in
C:\Folder\FolderLog.txt

I see 3 methods for FolderWatcher_** but I dont see a call to those in the code. I am very new to .net so I am not sure how they are being called

here is my complete code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;

    namespace Watcher
    {
        public partial class Watcher : ServiceBase
        {
            public Watcher()
            {
                InitializeComponent();
            }

            protected override void OnStart(string[] args)
            {

            }

            protected override void OnStop()
            {
            }

            private void FolderWatcher_Created(object sender, System.IO.FileSystemEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\FolderLog.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been created. ");
                writer.Close();
            }

            private void FolderWatcher_Deleted(object sender, System.IO.FileSystemEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\FolderLog.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been deleted. ");
                writer.Close();
            }

            private void FolderWatcher_Renamed(object sender, System.IO.RenamedEventArgs e)
            {
                TextWriter writer = new StreamWriter("C:\\folder\\log.txt", true);
                writer.WriteLine(DateTime.Now + " A new folder/file with name " + e.Name + " has been renamed. ");
                writer.Close();
            }

        }
    }

I have followed every single step in that tutorial. I have not seen anything that descibes how these methods are called. Any help would be great


问:
Strange 3-4 meter south offset in new MapDocument
I'm replacing and old application which shows points of interest in a map. The old app is running against an ArcGIS Desktop 10.0.5.4400 which publishes a base layer map service and a second map service that is a MapDocument with a collection of feature layers with the points to show. Coordinates of features in these layers are in a database in UTM format (European Datum 1950 UTM Zone 30N).

My first application version was running against the same map services, and was working fine, showing the base map and the features exactly in the same positions.

I have now started the next step: to create my own map document and load the same features from database. After some comparing activity, I ended up with a new map service that runs almost perfectly, except that my features are a little (3 or 4 meters) to the south comparing to the same features in the old map.

Funny enought, when I try to highlight some of those features (using a graphical layer I paint a circle at the coordinates and make it blink for a couple of seconds), the point is painted exactly at the position where the feature should be (3 or 4 meters up to the North, just where the old map shows the feature).

I've also tried to start from a copy of the old app's MapDocument, remove all query and XY data layers, and add my queries and my XY data layers there. The result is the same, so I guess the MapDocument itself is OK.

Anyone can give me some light on what can be creating this offset effect?

答:
The symbols used for the map are of 3D type, like balloons of different colors, so the feature should be down at the balloon's knot. So ArcGIS was doing it well, centering my symbol over the feature's location.

With this in mind, I found the old app's map document added an 8 point Y offset to all symbols. Adding this same offset to all my map's symbols solved the issue.


问:
Get hyperlink from unhidden href element, Python Selenium
This question has been asked before numerous times but I have tried all of the solutions I can find with no success. In short, I am scraping a table of members and can successfully collect all columns but the last which includes a button with a hyperlink to the member's email address. The hyperlink does not appear to be hidden as one can see the email when the cursor hovers over the button however I cannot select the button element and print out the hyperlink.
Below is the XPATH to the first email address of the table (column 5)

```<code>/html/body/div[5]/div[1]/main/div/div[5]/div/div/div/table/tbody/tr[1]/td[5]/a
</code>```

Below is the element for this same first email address of the table

```<code><a href="mailto:mmabbott@mac.com"><span id="ember2071" class="ember-view aia-icon"><svg class="icon" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" xml:space="preserve">
<path class="st0" d="M5.5,8.3v23.5h30.8V8.3H5.5z M8.6,26.4V13.6l6.3,6.4L8.6,26.4z M21.5,21.1c-0.2,0.3-0.9,0.3-1.2,0l-9.6-9.7
    h20.4L21.5,21.1z M18.1,23.3c0.7,0.7,1.7,1.1,2.8,1.1c1.1,0,2.1-0.4,2.8-1.1l1-1.1l6.3,6.4H10.7l6.3-6.5L18.1,23.3z M26.9,20
    l6.2-6.3v12.7L26.9,20z"></path>
</svg>
</span></a>
</code>```

Below is the code for my script for pulling the email addresses. Finally, I would like the script to output the email addresses into a CSV in a separate column from the other columns but that is for a separate discussion.

```<code>from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# open chrome
# driver = Webdriver.chrome("C:\Python Tools\chromedriver.exe")
s = Service("C:\Python Tools\chromedriver.exe")
driver = webdriver.Chrome(service=s)

# navigate to site and sign-in
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
driver.implicitly_wait(10)
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
username = driver.find_element(By.ID, "mat-input-0")
password = driver.find_element(By.ID, "mat-input-1")
username.send_keys("juzek2022@gmail.com")
password.send_keys("Test1234!")
driver.find_element(By.CLASS_NAME, "mat-button-wrapper").click()
driver.implicitly_wait(10)

# close cookies box
driver.find_element(By.XPATH, '//*[@id="truste-consent-button"]').click()

# navigate go member directory
driver.implicitly_wait(10)
driver.get("https://www.aia.org/member-directory?page%5Bnumber%5D=1")
driver.implicitly_wait(10)
# extract email addresses: list of tried and failed find element queries
# v1 = driver.find_elements(By.XPATH, "//button[contains(text(),'mailto')]")
# v1 = driver.find_elements(By.XPATH,'//a[contains(@href,".com")]')
# v1 = driver.find_elements(By.PARTIAL_LINK_TEXT, ".com")
# v1 = driver.find_elements(By.XPATH, '//a[contains(@href,"href")]')
# v1 = driver.find_elements(By.XPATH, '//a[@href="'+url+'"]')
# v1 = driver.find_elements(By.XPATH, "//a[contains(text(),'Verify Email')]").getAttribute('href')
# v1 = driver.find_elements(By.CLASS_NAME, "ember-view aia-icon").get_attribute("href")
# v1 = driver.find_elements(By.TAG_NAME, "a").getAttribute("href")
# v1 = driver.find_elements(By.XPATH,("//input[contains(td[5])]")).getAttribute("href")
# v1 = driver.find_elements(By.cssSelector("mailto").getAttribute("href")
# v1 = driver.find_elements(By.CLASS_NAME, "data-table").getAttribute("href")
# v1 = driver.find_elements(By.XPATH, "//div[@id='testId']/a").getAttribute("href")
# v1 = driver.find_elements(By.cssSelector("mailto")
# v1 = driver.find_elements(By.TAG_NAME, "td[5]")
# v1 = driver.find_elements(By.XPATH,("//input[contains(td[5])]"))
# v1 = driver.find_elements(By.TAG_NAME, "a")
# v1 = driver.find_elements(By.CLASS_NAME, "ember-view aia-icon")
print(v1)
# export email addresses to CSV
import csv

with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, quoting=csv.QUOTE_ALL,delimiter=';')
    writer.writerows(v1)
</code>```

Secondly, I would like to collect data from all five columns of the table and export to CSV, running a loop across all pages of the member directory. My draft code is below

```<code>from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# open chrome
# driver = Webdriver.chrome("C:\Python Tools\chromedriver.exe")
s = Service("C:\Python Tools\chromedriver.exe")
driver = webdriver.Chrome(service=s)

# navigate to site
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
driver.implicitly_wait(10)

# Enter login
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
username = driver.find_element(By.ID, "mat-input-0")
password = driver.find_element(By.ID, "mat-input-1")
username.send_keys("juzek2022@gmail.com")
password.send_keys("Test1234!")
driver.find_element(By.CLASS_NAME, "mat-button-wrapper").click()
driver.implicitly_wait(10)

# close cookies box
# old way driver.find_element_by_xpath('//*[@id="truste-consent-button"]').click()
driver.find_element(By.XPATH, '//*[@id="truste-consent-button"]').click()

driver.implicitly_wait(10)

# for holding the resultant list
element_list = []
for page in range(1, 3, 1):

    page_url = "https://www.aia.org/member-directory?page%5Bnumber%5D=" + str(page)
    driver.get(page_url)
    driver.implicitly_wait(10)
    # collect name, chapter, firm and location columns (not working, needs a loop)
    v1 = driver.find_elements(By.CLASS_NAME, "data-table")
    # collect email addresses (working)
    v2 = driver.find_elements(By.XPATH, '//a [contains(@href,"mailto")][@href]')
    for i in v2:
        email = i.get_attribute("href")
# loop across pages of directory
    for i in range(len(v1)):
        element_list.append([v1[i].text, v2[i].text])
# export to csv
import csv
with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, quoting=csv.QUOTE_ALL,delimiter=';')
    writer.writerows(element_list)
</code>```

答:
you should be using .get_attribute('href') instead of .getAttribute()

Therefore you can get all of the emails like this:

```<code>for item in driver.find_element(By.CLASS_NAME, 'data-table').find_elements(By.TAG_NAME, 'tr')[1:]:
    try:
        v1 = item.find_element(By.TAG_NAME, 'a').get_attribute("href")
    except:
        continue # element doesn't have an email
    print(v1)
</code>```

To get the rest of the table information you can do something like this:

```<code>data_table = []
for item in driver.find_element(By.CLASS_NAME, 'data-table').find_elements(By.TAG_NAME, 'tr')[1:]:
    elements = item.find_elements(By.TAG_NAME, 'td')
    name = elements[0].text
    aia_branch = elements[1].text
    company = elements[2].text
    location = elements[3].text
    data_table.append([name, aia_branch, company, location])
    try:
        v1 = item.find_element(By.TAG_NAME, 'a').get_attribute("href")
    except:
        continue # element doesn't have an email
    data_table[-1].append(v1)
    print(name, aia_branch, company, location, v1)
</code>```

Now to save all of that data to a csv you can do this:

```<code>with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, delimiter=',')
    writer.writerows(data_table)
</code>```

Body:
This question has been asked before numerous times but I have tried all of the solutions I can find with no success. In short, I am scraping a table of members and can successfully collect all columns but the last which includes a button with a hyperlink to the member's email address. The hyperlink does not appear to be hidden as one can see the email when the cursor hovers over the button however I cannot select the button element and print out the hyperlink.
Below is the XPATH to the first email address of the table (column 5)

/html/body/div[5]/div[1]/main/div/div[5]/div/div/div/table/tbody/tr[1]/td[5]/a

Below is the element for this same first email address of the table

<svg class="icon" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 40 40" style="enable-background:new 0 0 40 40;" xml:space="preserve">
<path class="st0" d="M5.5,8.3v23.5h30.8V8.3H5.5z M8.6,26.4V13.6l6.3,6.4L8.6,26.4z M21.5,21.1c-0.2,0.3-0.9,0.3-1.2,0l-9.6-9.7
    h20.4L21.5,21.1z M18.1,23.3c0.7,0.7,1.7,1.1,2.8,1.1c1.1,0,2.1-0.4,2.8-1.1l1-1.1l6.3,6.4H10.7l6.3-6.5L18.1,23.3z M26.9,20
    l6.2-6.3v12.7L26.9,20z"></path>
</svg>

Below is the code for my script for pulling the email addresses. Finally, I would like the script to output the email addresses into a CSV in a separate column from the other columns but that is for a separate discussion.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# open chrome
# driver = Webdriver.chrome("C:\Python Tools\chromedriver.exe")
s = Service("C:\Python Tools\chromedriver.exe")
driver = webdriver.Chrome(service=s)

# navigate to site and sign-in
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
driver.implicitly_wait(10)
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
username = driver.find_element(By.ID, "mat-input-0")
password = driver.find_element(By.ID, "mat-input-1")
username.send_keys("juzek2022@gmail.com")
password.send_keys("Test1234!")
driver.find_element(By.CLASS_NAME, "mat-button-wrapper").click()
driver.implicitly_wait(10)

# close cookies box
driver.find_element(By.XPATH, '//*[@id="truste-consent-button"]').click()

# navigate go member directory
driver.implicitly_wait(10)
driver.get("https://www.aia.org/member-directory?page%5Bnumber%5D=1")
driver.implicitly_wait(10)
# extract email addresses: list of tried and failed find element queries
# v1 = driver.find_elements(By.XPATH, "//button[contains(text(),'mailto')]")
# v1 = driver.find_elements(By.XPATH,'//a[contains(@href,".com")]')
# v1 = driver.find_elements(By.PARTIAL_LINK_TEXT, ".com")
# v1 = driver.find_elements(By.XPATH, '//a[contains(@href,"href")]')
# v1 = driver.find_elements(By.XPATH, '//a[@href="'+url+'"]')
# v1 = driver.find_elements(By.XPATH, "//a[contains(text(),'Verify Email')]").getAttribute('href')
# v1 = driver.find_elements(By.CLASS_NAME, "ember-view aia-icon").get_attribute("href")
# v1 = driver.find_elements(By.TAG_NAME, "a").getAttribute("href")
# v1 = driver.find_elements(By.XPATH,("//input[contains(td[5])]")).getAttribute("href")
# v1 = driver.find_elements(By.cssSelector("mailto").getAttribute("href")
# v1 = driver.find_elements(By.CLASS_NAME, "data-table").getAttribute("href")
# v1 = driver.find_elements(By.XPATH, "//div[@id='testId']/a").getAttribute("href")
# v1 = driver.find_elements(By.cssSelector("mailto")
# v1 = driver.find_elements(By.TAG_NAME, "td[5]")
# v1 = driver.find_elements(By.XPATH,("//input[contains(td[5])]"))
# v1 = driver.find_elements(By.TAG_NAME, "a")
# v1 = driver.find_elements(By.CLASS_NAME, "ember-view aia-icon")
print(v1)
# export email addresses to CSV
import csv

with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, quoting=csv.QUOTE_ALL,delimiter=';')
    writer.writerows(v1)

Secondly, I would like to collect data from all five columns of the table and export to CSV, running a loop across all pages of the member directory. My draft code is below

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

# open chrome
# driver = Webdriver.chrome("C:\Python Tools\chromedriver.exe")
s = Service("C:\Python Tools\chromedriver.exe")
driver = webdriver.Chrome(service=s)

# navigate to site
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
driver.implicitly_wait(10)

# Enter login
driver.get("https://account.aia.org/signin?redirectUrl=https:%2F%2Fwww.aia.org%2F")
username = driver.find_element(By.ID, "mat-input-0")
password = driver.find_element(By.ID, "mat-input-1")
username.send_keys("juzek2022@gmail.com")
password.send_keys("Test1234!")
driver.find_element(By.CLASS_NAME, "mat-button-wrapper").click()
driver.implicitly_wait(10)

# close cookies box
# old way driver.find_element_by_xpath('//*[@id="truste-consent-button"]').click()
driver.find_element(By.XPATH, '//*[@id="truste-consent-button"]').click()

driver.implicitly_wait(10)

# for holding the resultant list
element_list = []
for page in range(1, 3, 1):

    page_url = "https://www.aia.org/member-directory?page%5Bnumber%5D=" + str(page)
    driver.get(page_url)
    driver.implicitly_wait(10)
    # collect name, chapter, firm and location columns (not working, needs a loop)
    v1 = driver.find_elements(By.CLASS_NAME, "data-table")
    # collect email addresses (working)
    v2 = driver.find_elements(By.XPATH, '//a [contains(@href,"mailto")][@href]')
    for i in v2:
        email = i.get_attribute("href")
# loop across pages of directory
    for i in range(len(v1)):
        element_list.append([v1[i].text, v2[i].text])
# export to csv
import csv
with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, quoting=csv.QUOTE_ALL,delimiter=';')
    writer.writerows(element_list)

Body:
you should be using .get_attribute('href') instead of .getAttribute()

Therefore you can get all of the emails like this:

for item in driver.find_element(By.CLASS_NAME, 'data-table').find_elements(By.TAG_NAME, 'tr')[1:]:
    try:
        v1 = item.find_element(By.TAG_NAME, 'a').get_attribute("href")
    except:
        continue # element doesn't have an email
    print(v1)

To get the rest of the table information you can do something like this:

data_table = []
for item in driver.find_element(By.CLASS_NAME, 'data-table').find_elements(By.TAG_NAME, 'tr')[1:]:
    elements = item.find_elements(By.TAG_NAME, 'td')
    name = elements[0].text
    aia_branch = elements[1].text
    company = elements[2].text
    location = elements[3].text
    data_table.append([name, aia_branch, company, location])
    try:
        v1 = item.find_element(By.TAG_NAME, 'a').get_attribute("href")
    except:
        continue # element doesn't have an email
    data_table[-1].append(v1)
    print(name, aia_branch, company, location, v1)

Now to save all of that data to a csv you can do this:

with open('AIAMemberSearch.csv', 'w', newline='') as file:
    writer = csv.writer(file, delimiter=',')
    writer.writerows(data_table)


问:
Update JFrame panel in Thread infinite loop
I want to update jpanel in clients GUIs from the value I get from server continuously. But I can't see anything on the window.I can see the client frame if I set only one time but I need something like

```<code>while( get data from server != null){
   //update the jpanel
   // I tried
  frame.panel.setValue(data from server)
  frame.repaint()
  //and this one too
  frame.remove(old panel)
  frame.add(new JCustomPanel(with new value))
  frame.repaint()
}
</code>```

I can't share my code because my teacher prohibited it but I can't solve either.Please help me :c

答:
You need to do two things. First of all you need to create another thread, that will work with data independently from the main thread. Secondly, you need to use SwingUtilities.invokeLater method. This is a full example, that shows how it works. It changes label every second (Thread.sleep is used for delay in this example, don't use it in your real code).

```<code>import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class NewMain {

    // JFrame
    static JFrame frame;

    // JLabel
    static JLabel label;

    // Main class
    public static void main(String[] args)  {
        frame = new JFrame("panel");
        label = new JLabel();
        // Creating a panel to add label
        JPanel panel = new JPanel();
        panel.add(label);
        // Adding panel to frame
        frame.add(panel);
        // Setting the size of frame
        frame.setSize(300, 300);
        frame.show();
        doLoop();
    }

    private static void doLoop() {
        Thread newThread = new Thread(() -> {
            while (true) {
                SwingUtilities.invokeLater(() -> {
                    label.setText(new java.util.Date().toString());
                });
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        newThread.start();
    }
}
</code>```

Body:
I want to update jpanel in clients GUIs from the value I get from server continuously. But I can't see anything on the window.I can see the client frame if I set only one time but I need something like

while( get data from server != null){
   //update the jpanel
   // I tried
  frame.panel.setValue(data from server)
  frame.repaint()
  //and this one too
  frame.remove(old panel)
  frame.add(new JCustomPanel(with new value))
  frame.repaint()
}

I can't share my code because my teacher prohibited it but I can't solve either.Please help me :c

Body:
You need to do two things. First of all you need to create another thread, that will work with data independently from the main thread. Secondly, you need to use SwingUtilities.invokeLater method. This is a full example, that shows how it works. It changes label every second (Thread.sleep is used for delay in this example, don't use it in your real code).

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class NewMain {

    // JFrame
    static JFrame frame;

    // JLabel
    static JLabel label;

    // Main class
    public static void main(String[] args)  {
        frame = new JFrame("panel");
        label = new JLabel();
        // Creating a panel to add label
        JPanel panel = new JPanel();
        panel.add(label);
        // Adding panel to frame
        frame.add(panel);
        // Setting the size of frame
        frame.setSize(300, 300);
        frame.show();
        doLoop();
    }

    private static void doLoop() {
        Thread newThread = new Thread(() -> {
            while (true) {
                SwingUtilities.invokeLater(() -> {
                    label.setText(new java.util.Date().toString());
                });
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(NewMain.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        newThread.start();
    }
}


问:
How can I create an internal timer that will work with VCL and FMX?
I have a class that requires a timer. The class must work with both VCL and FMX. Unfortunately, the FMX timer is declared in FMX.Types and the VCL timer in Vcl.ExtCtrls.

As there is no conditional define like {$IFDEF FMX}xxx{$ENDIF} how do I use a timer in a cross platform class?

答:
TTimer is a component and thus supports interfaces. I use an interposer class to inject an ITimer interface to the original timer class and program only against this interface (which is common for both TTimer classes).

```<code>unit Mv.TimerIntf;

interface

uses
    System.Classes;

type
    ITimer = interface
        function PropGetEnabled: Boolean;
        function PropGetInterval: Cardinal;
        function PropGetOnTimer: TNotifyEvent;
        procedure PropSetEnabled(AValue: Boolean);
        procedure PropSetInterval(AValue: Cardinal);
        procedure PropSetOnTimer(AValue: TNotifyEvent);
        property Enabled: Boolean read PropGetEnabled write PropSetEnabled;
        property Interval: Cardinal read PropGetInterval write PropSetInterval;
        property OnTimer: TNotifyEvent read PropGetOnTimer write PropSetOnTimer;
    end;

implementation

end.
</code>```

and

```<code>unit Mv.VCL.Interposer.Timer;

interface

uses
    Mv.TimerIntf,
    System.Classes,
    VCL.ExtCtrls;

type

    TTimer = class(VCL.ExtCtrls.TTimer, ITimer)
        function PropGetEnabled: Boolean;
        function PropGetInterval: Cardinal;
        function PropGetOnTimer: TNotifyEvent;
        procedure PropSetEnabled(AValue: Boolean);
        procedure PropSetInterval(AValue: Cardinal);
        procedure PropSetOnTimer(AValue: TNotifyEvent);
    end;

implementation

function TTimer.PropGetEnabled: Boolean;
begin
    Result := Enabled;
end;

function TTimer.PropGetInterval: Cardinal;
begin
    Result := Interval;
end;

function TTimer.PropGetOnTimer: TNotifyEvent;
begin
    Result := OnTimer;
end;

procedure TTimer.PropSetEnabled(AValue: Boolean);
begin
    Enabled := AValue;
end;

procedure TTimer.PropSetInterval(AValue: Cardinal);
begin
    Interval := AValue;
end;

procedure TTimer.PropSetOnTimer(AValue: TNotifyEvent);
begin
    OnTimer := AValue;
end;

end.
</code>```

...

Usage: Code against the interface:

```<code>procedure InitTimer(ATimer: ITimer)
begin
    ATimer.Interval := 100;
    ATimer.OnTimer := DoWhatEver;
end;
</code>```

...

```<code>uses
    Vcl.ExtCtrls,
    Mv.VCL.Interposer.Timer;

type
    TForm1 = class(TForm)
        Timer1: TTimer;
    end;

//...

begin
    InitTimer(Timer1);
end;
</code>```

Body:
TTimer is a component and thus supports interfaces. I use an interposer class to inject an ITimer interface to the original timer class and program only against this interface (which is common for both TTimer classes).

unit Mv.TimerIntf;

interface

uses
    System.Classes;

type
    ITimer = interface
        function PropGetEnabled: Boolean;
        function PropGetInterval: Cardinal;
        function PropGetOnTimer: TNotifyEvent;
        procedure PropSetEnabled(AValue: Boolean);
        procedure PropSetInterval(AValue: Cardinal);
        procedure PropSetOnTimer(AValue: TNotifyEvent);
        property Enabled: Boolean read PropGetEnabled write PropSetEnabled;
        property Interval: Cardinal read PropGetInterval write PropSetInterval;
        property OnTimer: TNotifyEvent read PropGetOnTimer write PropSetOnTimer;
    end;

implementation

end.

and

unit Mv.VCL.Interposer.Timer;

interface

uses
    Mv.TimerIntf,
    System.Classes,
    VCL.ExtCtrls;

type

    TTimer = class(VCL.ExtCtrls.TTimer, ITimer)
        function PropGetEnabled: Boolean;
        function PropGetInterval: Cardinal;
        function PropGetOnTimer: TNotifyEvent;
        procedure PropSetEnabled(AValue: Boolean);
        procedure PropSetInterval(AValue: Cardinal);
        procedure PropSetOnTimer(AValue: TNotifyEvent);
    end;

implementation

function TTimer.PropGetEnabled: Boolean;
begin
    Result := Enabled;
end;

function TTimer.PropGetInterval: Cardinal;
begin
    Result := Interval;
end;

function TTimer.PropGetOnTimer: TNotifyEvent;
begin
    Result := OnTimer;
end;

procedure TTimer.PropSetEnabled(AValue: Boolean);
begin
    Enabled := AValue;
end;

procedure TTimer.PropSetInterval(AValue: Cardinal);
begin
    Interval := AValue;
end;

procedure TTimer.PropSetOnTimer(AValue: TNotifyEvent);
begin
    OnTimer := AValue;
end;

end.

...

Usage: Code against the interface:

procedure InitTimer(ATimer: ITimer)
begin
    ATimer.Interval := 100;
    ATimer.OnTimer := DoWhatEver;
end;

...

uses
    Vcl.ExtCtrls,
    Mv.VCL.Interposer.Timer;

type
    TForm1 = class(TForm)
        Timer1: TTimer;
    end;

//...

begin
    InitTimer(Timer1);
end;


问:
collisions in python pygame between a randomly spawned Object an player by hitboxes
I code for the first time with pygame and no one can help me ecause all may friends code wit javascript
I wrote those lines of Code and I want to do something when Food and player collide. This is my code and I want to do it the easiest way:

```<code>import pygame
import os
import random

pygame.init()
win_height = 400
win_width = 800
win = pygame.display.set_mode((win_width, win_height))

class Hero:
    def __init__(self, x, y):
        # Walk
        self.x = x
        self.y = y
        self.velx = 10
        self.vely = 6
        self.face_right = True
        self.face_left = False
        self.stepIndex = 0
        self.hitboxPlayer = pygame.Rect(self.x, self.y, 50, 112.5)
        # Jump
        self.jump = False

    def draw(self, win):
        self.hitboxPlayer = pygame.Rect(self.x, self.y, 50, 112.5)
        pygame.draw.rect(win, (0, 0, 0), self.hitboxPlayer, 1)
        if self.stepIndex >= 3:
            self.stepIndex = 0
        if self.face_left:
            win.blit(left[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1
        if self.face_right:
            win.blit(right[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1

    def jump_motion(self, userInput):
        if userInput[pygame.K_SPACE] and self.jump is False:
            self.jump = True
        if self.jump:
            self.y -= self.vely * 4
            self.vely -= 1
        if self.vely < -6:
            self.jump = False
            self.vely = 6

    def direction(self):
        if self.face_right:
            return 1
        if self.face_left:
            return -1

class Food:
    def __init__(self, lx, hx):
        self.y = 0
        self.speed = 5
        self.highestx = win_width
        self.x = random.randint(0,self.highestx)
        self.sprite = str(1)
        self.FoodCount = []
        self.hitboxFood = pygame.Rect(self.x, self.y, 50, 50)

    def draw(self):
        self.hitboxFood = pygame.Rect(self.x + 15, self.y + 15, 50, 50)
        pygame.draw.rect(win, (0, 0, 0), self.hitboxFood, 1)
        win.blit(food, (self.x,self.y))
        self.sprite = win.blit(food, (self.x,self.y))
        if self.y == win_height-200:
            print("Ground ")
        if snacks.hitboxFood.colliderect(player.hitboxPlayer) :
            print("hit")

    def move(self):
        self.y += self.speed

def draw_game():
    global tower_health, speed
    win.fill((0, 0, 0))
    win.blit(background, (0, 0))

    player.draw(win)

    for snack in snacks.FoodCount:
        snack.draw()
        snack.move()

    pygame.time.delay(30)
    pygame.display.update()

pygame.time.set_timer(pygame.USEREVENT, 1000)

snacks = Food(0, win_width)
player = Hero(250, 290)

run = True
while run:

        if event.type == pygame.USEREVENT:
            snacks.spawn()

    userInput = pygame.key.get_pressed()

    player.move_hero(userInput)
    player.jump_motion(userInput)

    draw_game()
</code>```

and I really don't know how to do this... I tried so much
tanks for helping!!!!!!!!!!!!!

答:
have you tried searching on Google pygame detect collision. I did and this is what I found, I hope this does help you.

Spending time searching on Google is the first thing you should think of when learning to code or using a new module.

Body:
I code for the first time with pygame and no one can help me ecause all may friends code wit javascript
I wrote those lines of Code and I want to do something when Food and player collide. This is my code and I want to do it the easiest way:

import pygame
import os
import random

pygame.init()
win_height = 400
win_width = 800
win = pygame.display.set_mode((win_width, win_height))

class Hero:
    def __init__(self, x, y):
        # Walk
        self.x = x
        self.y = y
        self.velx = 10
        self.vely = 6
        self.face_right = True
        self.face_left = False
        self.stepIndex = 0
        self.hitboxPlayer = pygame.Rect(self.x, self.y, 50, 112.5)
        # Jump
        self.jump = False

    def draw(self, win):
        self.hitboxPlayer = pygame.Rect(self.x, self.y, 50, 112.5)
        pygame.draw.rect(win, (0, 0, 0), self.hitboxPlayer, 1)
        if self.stepIndex >= 3:
            self.stepIndex = 0
        if self.face_left:
            win.blit(left[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1
        if self.face_right:
            win.blit(right[self.stepIndex], (self.x, self.y))
            self.stepIndex += 1

    def jump_motion(self, userInput):
        if userInput[pygame.K_SPACE] and self.jump is False:
            self.jump = True
        if self.jump:
            self.y -= self.vely * 4
            self.vely -= 1
        if self.vely < -6:
            self.jump = False
            self.vely = 6

    def direction(self):
        if self.face_right:
            return 1
        if self.face_left:
            return -1

class Food:
    def __init__(self, lx, hx):
        self.y = 0
        self.speed = 5
        self.highestx = win_width
        self.x = random.randint(0,self.highestx)
        self.sprite = str(1)
        self.FoodCount = []
        self.hitboxFood = pygame.Rect(self.x, self.y, 50, 50)

    def draw(self):
        self.hitboxFood = pygame.Rect(self.x + 15, self.y + 15, 50, 50)
        pygame.draw.rect(win, (0, 0, 0), self.hitboxFood, 1)
        win.blit(food, (self.x,self.y))
        self.sprite = win.blit(food, (self.x,self.y))
        if self.y == win_height-200:
            print("Ground ")
        if snacks.hitboxFood.colliderect(player.hitboxPlayer) :
            print("hit")

    def move(self):
        self.y += self.speed

def draw_game():
    global tower_health, speed
    win.fill((0, 0, 0))
    win.blit(background, (0, 0))

    player.draw(win)

    for snack in snacks.FoodCount:
        snack.draw()
        snack.move()

    pygame.time.delay(30)
    pygame.display.update()

pygame.time.set_timer(pygame.USEREVENT, 1000)

snacks = Food(0, win_width)
player = Hero(250, 290)

run = True
while run:

        if event.type == pygame.USEREVENT:
            snacks.spawn()

    userInput = pygame.key.get_pressed()

    player.move_hero(userInput)
    player.jump_motion(userInput)

    draw_game()

and I really don't know how to do this... I tried so much
tanks for helping!!!!!!!!!!!!!


问:
Initialize @StateObject with a parameter in SwiftUI
I would like to know if there is currently (at the time of asking, the first Xcode 12.0 Beta) a way to initialize a @StateObject with a parameter coming from an initializer.

To be more specific, this snippet of code works fine:

struct MyView: View {
  @StateObject var myObject = MyObject(id: 1)
}
```
<p>But this does not:</p>
<pre class="lang-swift prettyprint-override"><code>struct MyView: View {
  @StateObject var myObject: MyObject

  init(id: Int) {
    self.myObject = MyObject(id: id)
  }
}
</code>```

From what I understand the role of @StateObject is to make the view the owner of the object.
The current workaround I use is to pass the already initialized MyObject instance like this:

struct MyView: View {
  @ObservedObject var myObject: MyObject

  init(myObject: MyObject) {
    self.myObject = myObject
  }
}
```

But now, as far as I understand, the view that created the object owns it, while this view does not.

Thanks.

答:
Short Answer

The StateObject has the next init: init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType). This means that the StateObject will create an instance of the object at the right time - before running body for the first time. But it doesn't mean that you must declare that instance in one line in a View like @StateObject var viewModel = ContentViewModel().

The solution I found is to pass a closure as well and allow StateObject to create an instance on an object. This solution works well. For more details read the Long Answer below.

class ContentViewModel: ObservableObject {}

struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: @autoclosure @escaping () -> ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel())
    }
}

struct RootView: View {
    var body: some View {
        ContentView(viewModel: ContentViewModel())
    }
}
```
<p>No matter how many times <code>RootView</code> will create its <code>body</code>, the instance of <code>ContentViewModel</code> will be only one.</p>
<p>In this way, you are able to initialize <code>@StateObject</code> view model which has a parameter.</p>
<h2>Long Answer</h2>
<h4>@StateObject</h4>
<p>The <code>@StateObject</code> creates an instance of value just before running <code>body</code> for the first time (Data Essentials in SwiftUI). And it keeps this one instance of the value during all view lifetime. You can create an instance of a view somewhere outside of a <code>body</code> and you will see that <code>init</code> of <code>ContentViewModel</code> will not be called. See <code>onAppear</code> in the example below:</p>
<pre class="lang-swift prettyprint-override"><code>struct ContentView: View {
    @StateObject private var viewModel = ContentViewModel()
}

struct RootView: View {
    var body: some View {
        VStack(spacing: 20) {
        //...
        }
        .onAppear {
            // Instances of ContentViewModel will not be initialized
            _ = ContentView()
            _ = ContentView()
            _ = ContentView()

            // The next line of code
            // will create an instance of ContentViewModel.
            // Buy don't call body on your own in projects :)
            _ = ContentView().view
        }
    }
}
</code>```

Therefore it's important to delegate creating an instance to StateObject.

Why should not use StateObject(wrappedValue:) with instance

Let's consider an example when we create an instance of StateObject with _viewModel = StateObject(wrappedValue: viewModel) by passing a viewModel instance. When the root view will trigger an additional call of the body, then the new instance on viewModel will be created. If your view is an entire screen view, that will probably work fine. Despite this fact better not to use this solution. Because you're never sure when and how the parent view redrawing its children.

final class ContentViewModel: ObservableObject {
    @Published var text = "Hello @StateObject"

    init() { print("ViewModel init") }
    deinit { print("ViewModel deinit") }
}

struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel)
        print("ContentView init")
    }

    var body: some View { Text(viewModel.text) }
}

struct RootView: View {
    @State var isOn = false

    var body: some View {
        VStack(spacing: 20) {
            ContentView(viewModel: ContentViewModel())

            // This code is change the hierarchy of the root view.
            // Therefore all child views are created completely,
            // including 'ContentView'
            if isOn { Text("is on") }

            Button("Trigger") { isOn.toggle() }
        }
    }
}
```
<p>I tapped "Trigger" button 3 times and this is the output in the Xcode console:</p>
```
ViewModel init
ContentView init
ViewModel init
ContentView init
ViewModel init
ContentView init
ViewModel deinit
ViewModel init
ContentView init
ViewModel deinit
```
<p>As you can see, the instance of the <code>ContentViewModel</code> was created many times. That's because when a root view hierarchy is changed then everything in its <code>body</code> is created from scratch, including <code>ContentViewModel</code>. No matter that you set it to <code>@StateObject</code> in the child view. The matter that you call <code>init</code> in the root view the same amount of times as how the root view made an update of the <code>body</code>.</p>
<h4>Using closure</h4>
<p>As far as the <code>StateObject</code> use closure in the init - <code>init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType)</code> we can use this and pass the closure as well. Code exactly the same with previous section (<code>ContentViewModel</code> and <code>RootView</code>) but the only difference is using closure as init parameter to the <code>ContentView</code>:</p>
<pre class="lang-swift prettyprint-override"><code>struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: @autoclosure @escaping () -> ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel())
        print("ContentView init")
    }

    var body: some View { Text(viewModel.text) }
}
</code>```

After "Trigger" button was tapped 3 times - the output is next:

```
ContentView init
ViewModel init
ContentView init
ContentView init
ContentView init
```

You can see that only one instance of ContentViewModel has been created. Also the ContentViewModel was created after ContentView.

Btw, the easiest way to do the same is to have the property as internal/public and remove init:

struct ContentView: View {
    @StateObject var viewModel: ContentViewModel
}
```

The result is the same. But the viewModel can not be private property in this case.

Body:
I would like to know if there is currently (at the time of asking, the first Xcode 12.0 Beta) a way to initialize a @StateObject with a parameter coming from an initializer.

To be more specific, this snippet of code works fine:

struct MyView: View {
  @StateObject var myObject = MyObject(id: 1)
}

But this does not:

struct MyView: View {
  @StateObject var myObject: MyObject

  init(id: Int) {
    self.myObject = MyObject(id: id)
  }
}

From what I understand the role of @StateObject is to make the view the owner of the object.
The current workaround I use is to pass the already initialized MyObject instance like this:

struct MyView: View {
  @ObservedObject var myObject: MyObject

  init(myObject: MyObject) {
    self.myObject = myObject
  }
}

But now, as far as I understand, the view that created the object owns it, while this view does not.

Thanks.

Body:
Short Answer

The StateObject has the next init: init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType). This means that the StateObject will create an instance of the object at the right time - before running body for the first time. But it doesn't mean that you must declare that instance in one line in a View like @StateObject var viewModel = ContentViewModel().

The solution I found is to pass a closure as well and allow StateObject to create an instance on an object. This solution works well. For more details read the Long Answer below.

class ContentViewModel: ObservableObject {}

struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: @autoclosure @escaping () -> ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel())
    }
}

struct RootView: View {
    var body: some View {
        ContentView(viewModel: ContentViewModel())
    }
}

No matter how many times RootView will create its body, the instance of ContentViewModel will be only one.

In this way, you are able to initialize @StateObject view model which has a parameter.

Long Answer

@StateObject

The @StateObject creates an instance of value just before running body for the first time (Data Essentials in SwiftUI). And it keeps this one instance of the value during all view lifetime. You can create an instance of a view somewhere outside of a body and you will see that init of ContentViewModel will not be called. See onAppear in the example below:

struct ContentView: View {
    @StateObject private var viewModel = ContentViewModel()
}

struct RootView: View {
    var body: some View {
        VStack(spacing: 20) {
        //...
        }
        .onAppear {
            // Instances of ContentViewModel will not be initialized
            _ = ContentView()
            _ = ContentView()
            _ = ContentView()

            // The next line of code
            // will create an instance of ContentViewModel.
            // Buy don't call body on your own in projects :)
            _ = ContentView().view
        }
    }
}

Therefore it's important to delegate creating an instance to StateObject.

Why should not use StateObject(wrappedValue:) with instance

Let's consider an example when we create an instance of StateObject with _viewModel = StateObject(wrappedValue: viewModel) by passing a viewModel instance. When the root view will trigger an additional call of the body, then the new instance on viewModel will be created. If your view is an entire screen view, that will probably work fine. Despite this fact better not to use this solution. Because you're never sure when and how the parent view redrawing its children.

final class ContentViewModel: ObservableObject {
    @Published var text = "Hello @StateObject"

    init() { print("ViewModel init") }
    deinit { print("ViewModel deinit") }
}

struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel)
        print("ContentView init")
    }

    var body: some View { Text(viewModel.text) }
}

struct RootView: View {
    @State var isOn = false

    var body: some View {
        VStack(spacing: 20) {
            ContentView(viewModel: ContentViewModel())

            // This code is change the hierarchy of the root view.
            // Therefore all child views are created completely,
            // including 'ContentView'
            if isOn { Text("is on") }

            Button("Trigger") { isOn.toggle() }
        }
    }
}

I tapped "Trigger" button 3 times and this is the output in the Xcode console:

ViewModel init
ContentView init
ViewModel init
ContentView init
ViewModel init
ContentView init
ViewModel deinit
ViewModel init
ContentView init
ViewModel deinit

As you can see, the instance of the ContentViewModel was created many times. That's because when a root view hierarchy is changed then everything in its body is created from scratch, including ContentViewModel. No matter that you set it to @StateObject in the child view. The matter that you call init in the root view the same amount of times as how the root view made an update of the body.

Using closure

As far as the StateObject use closure in the init - init(wrappedValue thunk: @autoclosure @escaping () -> ObjectType) we can use this and pass the closure as well. Code exactly the same with previous section (ContentViewModel and RootView) but the only difference is using closure as init parameter to the ContentView:

struct ContentView: View {
    @StateObject private var viewModel: ContentViewModel

    init(viewModel: @autoclosure @escaping () -> ContentViewModel) {
        _viewModel = StateObject(wrappedValue: viewModel())
        print("ContentView init")
    }

    var body: some View { Text(viewModel.text) }
}

After "Trigger" button was tapped 3 times - the output is next:

ContentView init
ViewModel init
ContentView init
ContentView init
ContentView init

You can see that only one instance of ContentViewModel has been created. Also the ContentViewModel was created after ContentView.

Btw, the easiest way to do the same is to have the property as internal/public and remove init:

struct ContentView: View {
    @StateObject var viewModel: ContentViewModel
}

The result is the same. But the viewModel can not be private property in this case.