问:
Plaid Quickstart - Unable to fetch link_token (Python)
After having followed the instructions on https://dashboard.plaid.com/overview/sandbox.
I get the
following message on the frontend and the following  error on my terminal  from the backend when trying to get the Plaid Sandbox up and running. How do I get rid of the Unable to fetch link_token message on the frontend? I can only assume it has to do with end point @app.route('/api/auth', methods=['GET']) on the backend.

```<code> * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
127.0.0.1 - - [28/Jul/2021 10:58:55] "POST /api/info HTTP/1.1" 200 -
127.0.0.1 - - [28/Jul/2021 10:58:55] "GET /favicon.ico HTTP/1.1" 404 -
[2021-07-28 10:58:56,017] ERROR in app: Exception on /api/create_link_token [POST]
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connection.py", line 411, in connect
    self.sock = ssl_wrap_socket(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/cruzgonzalez/quickstart/python/server.py", line 196, in create_link_token
    response = client.link_token_create(request)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 769, in __call__
    return self.callable(self, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api/plaid_api.py", line 5843, in __link_token_create
    return self.call_with_http_info(**kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 831, in call_with_http_info
    return self.api_client.call_api(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 406, in call_api
    return self.__call_api(resource_path, method,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 193, in __call_api
    response_data = self.request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 452, in request
    return self.rest_client.POST(url,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/rest.py", line 264, in POST
    return self.request("POST", url,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/rest.py", line 150, in request
    r = self.pool_manager.request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/request.py", line 78, in request
    return self.request_encode_body(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/request.py", line 170, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/poolmanager.py", line 375, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/retry.py", line 574, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='sandbox.plaid.com', port=443): Max retries exceeded with url: /link/token/create (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))
127.0.0.1 - - [28/Jul/2021 10:58:56] "POST /api/create_link_token HTTP/1.1" 500 -
</code>```

This is my .env file

```<code>
PLAID_CLIENT_ID='XXXXXXXXXXX'
PLAID_SECRET='XXXXXXXXXXXXX'
PLAID_ENV='sandbox'
PLAID_PRODUCTS=auth,transactions
PLAID_COUNTRY_CODES=US,CA
# Only required for OAuth:
# Set PLAID_REDIRECT_URI to 'http://localhost:3000'
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
PLAID_REDIRECT_URI='http://localhost:3000'
</code>```

And my python file: server.py

```<code># Read env vars from .env file
from plaid.model.payment_amount import PaymentAmount
from plaid.model.products import Products
from plaid.model.country_code import CountryCode
from plaid.model.nullable_recipient_bacs import NullableRecipientBACS
from plaid.model.payment_initiation_address import PaymentInitiationAddress
from plaid.model.payment_initiation_recipient_create_request import PaymentInitiationRecipientCreateRequest
from plaid.model.payment_initiation_payment_create_request import PaymentInitiationPaymentCreateRequest
from plaid.model.payment_initiation_payment_get_request import PaymentInitiationPaymentGetRequest
from plaid.model.link_token_create_request_payment_initiation import LinkTokenCreateRequestPaymentInitiation
from plaid.model.item_public_token_exchange_request import ItemPublicTokenExchangeRequest
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.asset_report_create_request import AssetReportCreateRequest
from plaid.model.asset_report_create_request_options import AssetReportCreateRequestOptions
from plaid.model.asset_report_user import AssetReportUser
from plaid.model.asset_report_get_request import AssetReportGetRequest
from plaid.model.asset_report_pdf_get_request import AssetReportPDFGetRequest
from plaid.model.auth_get_request import AuthGetRequest
from plaid.model.transactions_get_request import TransactionsGetRequest
from plaid.model.transactions_get_request_options import TransactionsGetRequestOptions
from plaid.model.identity_get_request import IdentityGetRequest
from plaid.model.investments_transactions_get_request_options import InvestmentsTransactionsGetRequestOptions
from plaid.model.investments_transactions_get_request import InvestmentsTransactionsGetRequest
from plaid.model.accounts_balance_get_request import AccountsBalanceGetRequest
from plaid.model.accounts_get_request import AccountsGetRequest
from plaid.model.investments_holdings_get_request import InvestmentsHoldingsGetRequest
from plaid.model.item_get_request import ItemGetRequest
from plaid.model.institutions_get_by_id_request import InstitutionsGetByIdRequest
from plaid.api import plaid_api
from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify
from datetime import datetime
from datetime import timedelta
import plaid
import base64
import os
import datetime
import json
import time
from dotenv import load_dotenv
load_dotenv()

app = Flask(__name__)

# Fill in your Plaid API keys - https://dashboard.plaid.com/account/keys
PLAID_CLIENT_ID = os.getenv('PLAID_CLIENT_ID')
PLAID_SECRET = os.getenv('PLAID_SECRET')
# Use 'sandbox' to test with Plaid's Sandbox environment (username: user_good,
# password: pass_good)
# Use `development` to test with live users and credentials and `production`
# to go live
PLAID_ENV = os.getenv('PLAID_ENV', 'sandbox')
# PLAID_PRODUCTS is a comma-separated list of products to use when initializing
# Link. Note that this list must contain 'assets' in order for the app to be
# able to create and retrieve asset reports.
PLAID_PRODUCTS = os.getenv('PLAID_PRODUCTS', 'transactions').split(',')

# PLAID_COUNTRY_CODES is a comma-separated list of countries for which users
# will be able to select institutions from.
PLAID_COUNTRY_CODES = os.getenv('PLAID_COUNTRY_CODES', 'US').split(',')

def empty_to_none(field):
    value = os.getenv(field)
    if value is None or len(value) == 0:
        return None
    return value

host = plaid.Environment.Sandbox

if PLAID_ENV == 'sandbox':
    host = plaid.Environment.Sandbox

if PLAID_ENV == 'development':
    host = plaid.Environment.Development

if PLAID_ENV == 'production':
    host = plaid.Environment.Production

# Parameters used for the OAuth redirect Link flow.
#
# Set PLAID_REDIRECT_URI to 'http://localhost:3000/'
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
PLAID_REDIRECT_URI = empty_to_none('PLAID_REDIRECT_URI')

configuration = plaid.Configuration(
    host=host,
    api_key={
        'clientId': PLAID_CLIENT_ID,
        'secret': PLAID_SECRET,
        'plaidVersion': '2020-09-14'
    }
)

api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)

products = []
for product in PLAID_PRODUCTS:
    products.append(Products(product))

# We store the access_token in memory - in production, store it in a secure
# persistent data store.
access_token = None
# The payment_id is only relevant for the UK Payment Initiation product.
# We store the payment_id in memory - in production, store it in a secure
# persistent data store.
payment_id = None

item_id = None

@app.route('/api/info', methods=['POST'])
def info():
    global access_token
    global item_id
    return jsonify({
        'item_id': item_id,
        'access_token': access_token,
        'products': PLAID_PRODUCTS
    })

@app.route('/api/create_link_token_for_payment', methods=['POST'])
def create_link_token_for_payment():
    global payment_id
    try:
        request = PaymentInitiationRecipientCreateRequest(
            name='John Doe',
            bacs=NullableRecipientBACS(account='26207729', sort_code='560029'),
            address=PaymentInitiationAddress(
                street=['street name 999'],
                city='city',
                postal_code='99999',
                country='GB'
            )
        )
        response = client.payment_initiation_recipient_create(
            request)
        recipient_id = response['recipient_id']

        request = PaymentInitiationPaymentCreateRequest(
            recipient_id=recipient_id,
            reference='TestPayment',
            amount=PaymentAmount(
                currency='GBP',
                value=100.00
            )
        )
        response = client.payment_initiation_payment_create(
            request
        )
        pretty_print_response(response.to_dict())
        payment_id = response['payment_id']
        request = LinkTokenCreateRequest(
            products=[Products('payment_initiation')],
            client_name='Plaid Test',
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES)),
            language='en',
            user=LinkTokenCreateRequestUser(
                client_user_id=str(time.time())
            ),
            payment_initiation=LinkTokenCreateRequestPaymentInitiation(
                payment_id=payment_id
            )
        )
        response = client.link_token_create(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

@app.route('/api/create_link_token', methods=['POST'])
def create_link_token():
    try:
        request = LinkTokenCreateRequest(
            products=products,
            client_name="Plaid Quickstart",
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES)),
            language='en',
            user=LinkTokenCreateRequestUser(
                client_user_id=str(time.time())
            )
        )

        # create link token
        response = client.link_token_create(request)
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

# Exchange token flow - exchange a Link public_token for
# an API access_token
# https://plaid.com/docs/#exchange-token-flow

@app.route('/api/set_access_token', methods=['POST'])
def get_access_token():
    global access_token
    global item_id
    public_token = request.form['public_token']
    try:
        exchange_request = ItemPublicTokenExchangeRequest(
            public_token=public_token)
        exchange_response = client.item_public_token_exchange(exchange_request)
        access_token = exchange_response['access_token']
        item_id = exchange_response['item_id']
        return jsonify(exchange_response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

# Retrieve ACH or ETF account numbers for an Item
# https://plaid.com/docs/#auth

@app.route('/api/auth', methods=['GET'])
def get_auth():
    try:
       request = AuthGetRequest(
            access_token=access_token
        )
       response = client.auth_get(request)
       pretty_print_response(response.to_dict())
       return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Transactions for an Item
# https://plaid.com/docs/#transactions

@app.route('/api/transactions', methods=['GET'])
def get_transactions():
    # Pull transactions for the last 30 days
    start_date = (datetime.datetime.now() - timedelta(days=30))
    end_date = datetime.datetime.now()
    try:
        options = TransactionsGetRequestOptions()
        request = TransactionsGetRequest(
            access_token=access_token,
            start_date=start_date.date(),
            end_date=end_date.date(),
            options=options
        )
        response = client.transactions_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Identity data for an Item
# https://plaid.com/docs/#identity

@app.route('/api/identity', methods=['GET'])
def get_identity():
    try:
        request = IdentityGetRequest(
            access_token=access_token
        )
        response = client.identity_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(
            {'error': None, 'identity': response.to_dict()['accounts']})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve real-time balance data for each of an Item's accounts
# https://plaid.com/docs/#balance

@app.route('/api/balance', methods=['GET'])
def get_balance():
    try:
        request = AccountsBalanceGetRequest(
            access_token=access_token
        )
        response = client.accounts_balance_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve an Item's accounts
# https://plaid.com/docs/#accounts

@app.route('/api/accounts', methods=['GET'])
def get_accounts():
    try:
        request = AccountsGetRequest(
            access_token=access_token
        )
        response = client.accounts_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Create and then retrieve an Asset Report for one or more Items. Note that an
# Asset Report can contain up to 100 items, but for simplicity we're only
# including one Item here.
# https://plaid.com/docs/#assets

@app.route('/api/assets', methods=['GET'])
def get_assets():
    try:
        request = AssetReportCreateRequest(
            access_tokens=[access_token],
            days_requested=60,
            options=AssetReportCreateRequestOptions(
                webhook='https://www.example.com',
                client_report_id='123',
                user=AssetReportUser(
                    client_user_id='789',
                    first_name='Jane',
                    middle_name='Leah',
                    last_name='Doe',
                    ssn='123-45-6789',
                    phone_number='(555) 123-4567',
                    email='jane.doe@example.com',
                )
            )
        )

        response = client.asset_report_create(request)
        pretty_print_response(response.to_dict())
        asset_report_token = response['asset_report_token']
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

    # Poll for the completion of the Asset Report.
    num_retries_remaining = 20
    asset_report_json = None
    while num_retries_remaining > 0:
        try:
            request = AssetReportGetRequest(
                asset_report_token=asset_report_token,
            )
            response = client.asset_report_get(request)
            asset_report_json = response['report']
            break
        except plaid.ApiException as e:
            response = json.loads(e.body)
            if response['error_code'] == 'PRODUCT_NOT_READY':
                num_retries_remaining -= 1
                time.sleep(1)
                continue
        error_response = format_error(e)
        return jsonify(error_response)
    if asset_report_json is None:
        return jsonify({'error': {'status_code': e.status, 'display_message':
                                  'Timed out when polling for Asset Report', 'error_code': '', 'error_type': ''}})

    asset_report_pdf = None
    try:
        request = AssetReportPDFGetRequest(
            asset_report_token=asset_report_token,
        )
        pdf = client.asset_report_pdf_get(request)
        return jsonify({
            'error': None,
            'json': asset_report_json.to_dict(),
            'pdf': base64.b64encode(pdf.read()).decode('utf-8'),
        })
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve investment holdings data for an Item
# https://plaid.com/docs/#investments

@app.route('/api/holdings', methods=['GET'])
def get_holdings():
    try:
        request = InvestmentsHoldingsGetRequest(access_token=access_token)
        response = client.investments_holdings_get(request)
        pretty_print_response(response.to_dict())
        return jsonify({'error': None, 'holdings': response.to_dict()})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Investment Transactions for an Item
# https://plaid.com/docs/#investments

@app.route('/api/investment_transactions', methods=['GET'])
def get_investment_transactions():
    # Pull transactions for the last 30 days

    start_date = (datetime.datetime.now() - timedelta(days=(30)))
    end_date = datetime.datetime.now()
    try:
        options = InvestmentsTransactionsGetRequestOptions()
        request = InvestmentsTransactionsGetRequest(
            access_token=access_token,
            start_date=start_date.date(),
            end_date=end_date.date(),
            options=options
        )
        response = client.investment_transactions_get(
            request)
        pretty_print_response(response.to_dict())
        return jsonify(
            {'error': None, 'investment_transactions': response.to_dict()})

    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# This functionality is only relevant for the UK Payment Initiation product.
# Retrieve Payment for a specified Payment ID

@app.route('/api/payment', methods=['GET'])
def payment():
    global payment_id
    try:
        request = PaymentInitiationPaymentGetRequest(payment_id=payment_id)
        response = client.payment_initiation_payment_get(request)
        pretty_print_response(response.to_dict())
        return jsonify({'error': None, 'payment': response.to_dict()})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve high-level information about an Item
# https://plaid.com/docs/#retrieve-item

@app.route('/api/item', methods=['GET'])
def item():
    try:
        request = ItemGetRequest(access_token=access_token)
        response = client.item_get(request)
        request = InstitutionsGetByIdRequest(
            institution_id=response['item']['institution_id'],
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES))
        )
        institution_response = client.institutions_get_by_id(request)
        pretty_print_response(response.to_dict())
        pretty_print_response(institution_response.to_dict())
        return jsonify({'error': None, 'item': response.to_dict()[
            'item'], 'institution': institution_response.to_dict()['institution']})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

def pretty_print_response(response):
  print(json.dumps(response, indent=2, sort_keys=True, default=str))

def format_error(e):
    response = json.loads(e.body)
    return {'error': {'status_code': e.status, 'display_message':
                      response['error_message'], 'error_code': response['error_code'], 'error_type': response['error_type']}}

if __name__ == '__main__':
    app.run(port=os.getenv('PORT', 8000))

</code>```

答: This can also be caused by an outdated requests package. My team had the same issue and upgrading requests to the latest version (currently 2.27.1) solved it.

Body:
After having followed the instructions on https://dashboard.plaid.com/overview/sandbox.
I get the
following message on the frontend and the following  error on my terminal  from the backend when trying to get the Plaid Sandbox up and running. How do I get rid of the Unable to fetch link_token message on the frontend? I can only assume it has to do with end point @app.route('/api/auth', methods=['GET']) on the backend.

 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:8000/ (Press CTRL+C to quit)
127.0.0.1 - - [28/Jul/2021 10:58:55] "POST /api/info HTTP/1.1" 200 -
127.0.0.1 - - [28/Jul/2021 10:58:55] "GET /favicon.ico HTTP/1.1" 404 -
[2021-07-28 10:58:56,017] ERROR in app: Exception on /api/create_link_token [POST]
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 699, in urlopen
    httplib_response = self._make_request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 382, in _make_request
    self._validate_conn(conn)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 1010, in _validate_conn
    conn.connect()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connection.py", line 411, in connect
    self.sock = ssl_wrap_socket(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 449, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/ssl_.py", line 493, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/cruzgonzalez/quickstart/python/server.py", line 196, in create_link_token
    response = client.link_token_create(request)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 769, in __call__
    return self.callable(self, *args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api/plaid_api.py", line 5843, in __link_token_create
    return self.call_with_http_info(**kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 831, in call_with_http_info
    return self.api_client.call_api(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 406, in call_api
    return self.__call_api(resource_path, method,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 193, in __call_api
    response_data = self.request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/api_client.py", line 452, in request
    return self.rest_client.POST(url,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/rest.py", line 264, in POST
    return self.request("POST", url,
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/plaid/rest.py", line 150, in request
    r = self.pool_manager.request(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/request.py", line 78, in request
    return self.request_encode_body(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/request.py", line 170, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/poolmanager.py", line 375, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 783, in urlopen
    return self.urlopen(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/connectionpool.py", line 755, in urlopen
    retries = retries.increment(
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/urllib3/util/retry.py", line 574, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='sandbox.plaid.com', port=443): Max retries exceeded with url: /link/token/create (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)')))
127.0.0.1 - - [28/Jul/2021 10:58:56] "POST /api/create_link_token HTTP/1.1" 500 -

This is my .env file

PLAID_CLIENT_ID='XXXXXXXXXXX'
PLAID_SECRET='XXXXXXXXXXXXX'
PLAID_ENV='sandbox'
PLAID_PRODUCTS=auth,transactions
PLAID_COUNTRY_CODES=US,CA
# Only required for OAuth:
# Set PLAID_REDIRECT_URI to 'http://localhost:3000'
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
PLAID_REDIRECT_URI='http://localhost:3000'

And my python file: server.py

# Read env vars from .env file
from plaid.model.payment_amount import PaymentAmount
from plaid.model.products import Products
from plaid.model.country_code import CountryCode
from plaid.model.nullable_recipient_bacs import NullableRecipientBACS
from plaid.model.payment_initiation_address import PaymentInitiationAddress
from plaid.model.payment_initiation_recipient_create_request import PaymentInitiationRecipientCreateRequest
from plaid.model.payment_initiation_payment_create_request import PaymentInitiationPaymentCreateRequest
from plaid.model.payment_initiation_payment_get_request import PaymentInitiationPaymentGetRequest
from plaid.model.link_token_create_request_payment_initiation import LinkTokenCreateRequestPaymentInitiation
from plaid.model.item_public_token_exchange_request import ItemPublicTokenExchangeRequest
from plaid.model.link_token_create_request import LinkTokenCreateRequest
from plaid.model.link_token_create_request_user import LinkTokenCreateRequestUser
from plaid.model.asset_report_create_request import AssetReportCreateRequest
from plaid.model.asset_report_create_request_options import AssetReportCreateRequestOptions
from plaid.model.asset_report_user import AssetReportUser
from plaid.model.asset_report_get_request import AssetReportGetRequest
from plaid.model.asset_report_pdf_get_request import AssetReportPDFGetRequest
from plaid.model.auth_get_request import AuthGetRequest
from plaid.model.transactions_get_request import TransactionsGetRequest
from plaid.model.transactions_get_request_options import TransactionsGetRequestOptions
from plaid.model.identity_get_request import IdentityGetRequest
from plaid.model.investments_transactions_get_request_options import InvestmentsTransactionsGetRequestOptions
from plaid.model.investments_transactions_get_request import InvestmentsTransactionsGetRequest
from plaid.model.accounts_balance_get_request import AccountsBalanceGetRequest
from plaid.model.accounts_get_request import AccountsGetRequest
from plaid.model.investments_holdings_get_request import InvestmentsHoldingsGetRequest
from plaid.model.item_get_request import ItemGetRequest
from plaid.model.institutions_get_by_id_request import InstitutionsGetByIdRequest
from plaid.api import plaid_api
from flask import Flask
from flask import render_template
from flask import request
from flask import jsonify
from datetime import datetime
from datetime import timedelta
import plaid
import base64
import os
import datetime
import json
import time
from dotenv import load_dotenv
load_dotenv()

app = Flask(__name__)

# Fill in your Plaid API keys - https://dashboard.plaid.com/account/keys
PLAID_CLIENT_ID = os.getenv('PLAID_CLIENT_ID')
PLAID_SECRET = os.getenv('PLAID_SECRET')
# Use 'sandbox' to test with Plaid's Sandbox environment (username: user_good,
# password: pass_good)
# Use `development` to test with live users and credentials and `production`
# to go live
PLAID_ENV = os.getenv('PLAID_ENV', 'sandbox')
# PLAID_PRODUCTS is a comma-separated list of products to use when initializing
# Link. Note that this list must contain 'assets' in order for the app to be
# able to create and retrieve asset reports.
PLAID_PRODUCTS = os.getenv('PLAID_PRODUCTS', 'transactions').split(',')

# PLAID_COUNTRY_CODES is a comma-separated list of countries for which users
# will be able to select institutions from.
PLAID_COUNTRY_CODES = os.getenv('PLAID_COUNTRY_CODES', 'US').split(',')

def empty_to_none(field):
    value = os.getenv(field)
    if value is None or len(value) == 0:
        return None
    return value

host = plaid.Environment.Sandbox

if PLAID_ENV == 'sandbox':
    host = plaid.Environment.Sandbox

if PLAID_ENV == 'development':
    host = plaid.Environment.Development

if PLAID_ENV == 'production':
    host = plaid.Environment.Production

# Parameters used for the OAuth redirect Link flow.
#
# Set PLAID_REDIRECT_URI to 'http://localhost:3000/'
# The OAuth redirect flow requires an endpoint on the developer's website
# that the bank website should redirect to. You will need to configure
# this redirect URI for your client ID through the Plaid developer dashboard
# at https://dashboard.plaid.com/team/api.
PLAID_REDIRECT_URI = empty_to_none('PLAID_REDIRECT_URI')

configuration = plaid.Configuration(
    host=host,
    api_key={
        'clientId': PLAID_CLIENT_ID,
        'secret': PLAID_SECRET,
        'plaidVersion': '2020-09-14'
    }
)

api_client = plaid.ApiClient(configuration)
client = plaid_api.PlaidApi(api_client)

products = []
for product in PLAID_PRODUCTS:
    products.append(Products(product))

# We store the access_token in memory - in production, store it in a secure
# persistent data store.
access_token = None
# The payment_id is only relevant for the UK Payment Initiation product.
# We store the payment_id in memory - in production, store it in a secure
# persistent data store.
payment_id = None

item_id = None

@app.route('/api/info', methods=['POST'])
def info():
    global access_token
    global item_id
    return jsonify({
        'item_id': item_id,
        'access_token': access_token,
        'products': PLAID_PRODUCTS
    })

@app.route('/api/create_link_token_for_payment', methods=['POST'])
def create_link_token_for_payment():
    global payment_id
    try:
        request = PaymentInitiationRecipientCreateRequest(
            name='John Doe',
            bacs=NullableRecipientBACS(account='26207729', sort_code='560029'),
            address=PaymentInitiationAddress(
                street=['street name 999'],
                city='city',
                postal_code='99999',
                country='GB'
            )
        )
        response = client.payment_initiation_recipient_create(
            request)
        recipient_id = response['recipient_id']

        request = PaymentInitiationPaymentCreateRequest(
            recipient_id=recipient_id,
            reference='TestPayment',
            amount=PaymentAmount(
                currency='GBP',
                value=100.00
            )
        )
        response = client.payment_initiation_payment_create(
            request
        )
        pretty_print_response(response.to_dict())
        payment_id = response['payment_id']
        request = LinkTokenCreateRequest(
            products=[Products('payment_initiation')],
            client_name='Plaid Test',
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES)),
            language='en',
            user=LinkTokenCreateRequestUser(
                client_user_id=str(time.time())
            ),
            payment_initiation=LinkTokenCreateRequestPaymentInitiation(
                payment_id=payment_id
            )
        )
        response = client.link_token_create(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

@app.route('/api/create_link_token', methods=['POST'])
def create_link_token():
    try:
        request = LinkTokenCreateRequest(
            products=products,
            client_name="Plaid Quickstart",
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES)),
            language='en',
            user=LinkTokenCreateRequestUser(
                client_user_id=str(time.time())
            )
        )

        # create link token
        response = client.link_token_create(request)
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

# Exchange token flow - exchange a Link public_token for
# an API access_token
# https://plaid.com/docs/#exchange-token-flow

@app.route('/api/set_access_token', methods=['POST'])
def get_access_token():
    global access_token
    global item_id
    public_token = request.form['public_token']
    try:
        exchange_request = ItemPublicTokenExchangeRequest(
            public_token=public_token)
        exchange_response = client.item_public_token_exchange(exchange_request)
        access_token = exchange_response['access_token']
        item_id = exchange_response['item_id']
        return jsonify(exchange_response.to_dict())
    except plaid.ApiException as e:
        return json.loads(e.body)

# Retrieve ACH or ETF account numbers for an Item
# https://plaid.com/docs/#auth

@app.route('/api/auth', methods=['GET'])
def get_auth():
    try:
       request = AuthGetRequest(
            access_token=access_token
        )
       response = client.auth_get(request)
       pretty_print_response(response.to_dict())
       return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Transactions for an Item
# https://plaid.com/docs/#transactions

@app.route('/api/transactions', methods=['GET'])
def get_transactions():
    # Pull transactions for the last 30 days
    start_date = (datetime.datetime.now() - timedelta(days=30))
    end_date = datetime.datetime.now()
    try:
        options = TransactionsGetRequestOptions()
        request = TransactionsGetRequest(
            access_token=access_token,
            start_date=start_date.date(),
            end_date=end_date.date(),
            options=options
        )
        response = client.transactions_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Identity data for an Item
# https://plaid.com/docs/#identity

@app.route('/api/identity', methods=['GET'])
def get_identity():
    try:
        request = IdentityGetRequest(
            access_token=access_token
        )
        response = client.identity_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(
            {'error': None, 'identity': response.to_dict()['accounts']})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve real-time balance data for each of an Item's accounts
# https://plaid.com/docs/#balance

@app.route('/api/balance', methods=['GET'])
def get_balance():
    try:
        request = AccountsBalanceGetRequest(
            access_token=access_token
        )
        response = client.accounts_balance_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve an Item's accounts
# https://plaid.com/docs/#accounts

@app.route('/api/accounts', methods=['GET'])
def get_accounts():
    try:
        request = AccountsGetRequest(
            access_token=access_token
        )
        response = client.accounts_get(request)
        pretty_print_response(response.to_dict())
        return jsonify(response.to_dict())
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Create and then retrieve an Asset Report for one or more Items. Note that an
# Asset Report can contain up to 100 items, but for simplicity we're only
# including one Item here.
# https://plaid.com/docs/#assets

@app.route('/api/assets', methods=['GET'])
def get_assets():
    try:
        request = AssetReportCreateRequest(
            access_tokens=[access_token],
            days_requested=60,
            options=AssetReportCreateRequestOptions(
                webhook='https://www.example.com',
                client_report_id='123',
                user=AssetReportUser(
                    client_user_id='789',
                    first_name='Jane',
                    middle_name='Leah',
                    last_name='Doe',
                    ssn='123-45-6789',
                    phone_number='(555) 123-4567',
                    email='jane.doe@example.com',
                )
            )
        )

        response = client.asset_report_create(request)
        pretty_print_response(response.to_dict())
        asset_report_token = response['asset_report_token']
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

    # Poll for the completion of the Asset Report.
    num_retries_remaining = 20
    asset_report_json = None
    while num_retries_remaining > 0:
        try:
            request = AssetReportGetRequest(
                asset_report_token=asset_report_token,
            )
            response = client.asset_report_get(request)
            asset_report_json = response['report']
            break
        except plaid.ApiException as e:
            response = json.loads(e.body)
            if response['error_code'] == 'PRODUCT_NOT_READY':
                num_retries_remaining -= 1
                time.sleep(1)
                continue
        error_response = format_error(e)
        return jsonify(error_response)
    if asset_report_json is None:
        return jsonify({'error': {'status_code': e.status, 'display_message':
                                  'Timed out when polling for Asset Report', 'error_code': '', 'error_type': ''}})

    asset_report_pdf = None
    try:
        request = AssetReportPDFGetRequest(
            asset_report_token=asset_report_token,
        )
        pdf = client.asset_report_pdf_get(request)
        return jsonify({
            'error': None,
            'json': asset_report_json.to_dict(),
            'pdf': base64.b64encode(pdf.read()).decode('utf-8'),
        })
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve investment holdings data for an Item
# https://plaid.com/docs/#investments

@app.route('/api/holdings', methods=['GET'])
def get_holdings():
    try:
        request = InvestmentsHoldingsGetRequest(access_token=access_token)
        response = client.investments_holdings_get(request)
        pretty_print_response(response.to_dict())
        return jsonify({'error': None, 'holdings': response.to_dict()})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve Investment Transactions for an Item
# https://plaid.com/docs/#investments

@app.route('/api/investment_transactions', methods=['GET'])
def get_investment_transactions():
    # Pull transactions for the last 30 days

    start_date = (datetime.datetime.now() - timedelta(days=(30)))
    end_date = datetime.datetime.now()
    try:
        options = InvestmentsTransactionsGetRequestOptions()
        request = InvestmentsTransactionsGetRequest(
            access_token=access_token,
            start_date=start_date.date(),
            end_date=end_date.date(),
            options=options
        )
        response = client.investment_transactions_get(
            request)
        pretty_print_response(response.to_dict())
        return jsonify(
            {'error': None, 'investment_transactions': response.to_dict()})

    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# This functionality is only relevant for the UK Payment Initiation product.
# Retrieve Payment for a specified Payment ID

@app.route('/api/payment', methods=['GET'])
def payment():
    global payment_id
    try:
        request = PaymentInitiationPaymentGetRequest(payment_id=payment_id)
        response = client.payment_initiation_payment_get(request)
        pretty_print_response(response.to_dict())
        return jsonify({'error': None, 'payment': response.to_dict()})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

# Retrieve high-level information about an Item
# https://plaid.com/docs/#retrieve-item

@app.route('/api/item', methods=['GET'])
def item():
    try:
        request = ItemGetRequest(access_token=access_token)
        response = client.item_get(request)
        request = InstitutionsGetByIdRequest(
            institution_id=response['item']['institution_id'],
            country_codes=list(map(lambda x: CountryCode(x), PLAID_COUNTRY_CODES))
        )
        institution_response = client.institutions_get_by_id(request)
        pretty_print_response(response.to_dict())
        pretty_print_response(institution_response.to_dict())
        return jsonify({'error': None, 'item': response.to_dict()[
            'item'], 'institution': institution_response.to_dict()['institution']})
    except plaid.ApiException as e:
        error_response = format_error(e)
        return jsonify(error_response)

def pretty_print_response(response):
  print(json.dumps(response, indent=2, sort_keys=True, default=str))

def format_error(e):
    response = json.loads(e.body)
    return {'error': {'status_code': e.status, 'display_message':
                      response['error_message'], 'error_code': response['error_code'], 'error_type': response['error_type']}}

if __name__ == '__main__':
    app.run(port=os.getenv('PORT', 8000))


来源: stackexchange

问:
Why yacc have memory leak at exit?
when I execute my lex/yacc program with valgrind, it find memory leak. But I would know if it's possible to delete this memory leak. The output of valgrind is:

```<code>==10006==
==10006== HEAP SUMMARY:
==10006==     in use at exit: 16,458 bytes in 3 blocks
==10006==   total heap usage: 13 allocs, 10 frees, 16,684 bytes allocated
==10006==
==10006== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x402411: yyensure_buffer_stack (lex.yy.c:1552)
==10006==    by 0x400DA9: yylex (lex.yy.c:686)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== 64 bytes in 1 blocks are still reachable in loss record 2 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x401FA5: yy_create_buffer (lex.yy.c:1387)
==10006==    by 0x400DD3: yylex (lex.yy.c:688)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== 16,386 bytes in 1 blocks are still reachable in loss record 3 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x401FDC: yy_create_buffer (lex.yy.c:1396)
==10006==    by 0x400DD3: yylex (lex.yy.c:688)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== LEAK SUMMARY:
==10006==    definitely lost: 0 bytes in 0 blocks
==10006==    indirectly lost: 0 bytes in 0 blocks
==10006==      possibly lost: 0 bytes in 0 blocks
==10006==    still reachable: 16,458 bytes in 3 blocks
==10006==         suppressed: 0 bytes in 0 blocks
==10006==
==10006== For counts of detected and suppressed errors, rerun with: -v
==10006== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
</code>```

And my lex:

```<code>Chiffre [0-9]
Lettre [a-zA-Z]
Alphanum ({Chiffre}{Lettre})+

%{

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.tab.h"

%}
%%
-[a-zA-Z]+ {
yylval.
string = strdup(yytext);
    return OPTION;
}

[a-zA-Z0-9_\-./]+ {
    yylval.string = strdup(yytext);
    return WORD;
}
"||" {
return OR;
}
"|" {
return PIPE;
}
"&&" {
return AND;
}
"&" {
    return AMPERSAND;
}
";" {
return SEMICOLON;
}
"2>" {
return
ERR_GREAT;
}

">&" {
return
GREAT_AMP;
}

"2>>" {
return
ERR_GREAT_GREAT;
}
">>&" {
return
GREAT_GREAT_AMP;
}
">>" {
return
GREAT_GREAT;
}

">" {
return
GREAT;
}

"<" {
return
LESS;
}

[ \t]+ {
}

"\n" {
return 0;
}

%%
</code>```

And my yacc file:

```<code>%{
#include <stdio.h>
#include "executor/CmdArg.h"
#include "executor/Command.h"
#include "print.h"
int yyerror(const char *msg) {
    return fprintf(stderr, "YACC: %s\n", msg);
}
%}

%union {
    int number;
    char *string;
};
%token<string> WORD
%token<string> OPTION
%destructor {
free($$);
} <string>
%token<void> SEMICOLON
%token OR AND PIPE AMPERSAND GREAT GREAT_GREAT LESS ERR_GREAT ERR_GREAT_GREAT GREAT_AMP GREAT_GREAT_AMP
%error-verbose
%%

pipeline: cmd_args
background SEMICOLON
pipeline{
end_cmd(SEQUENCING_SEQUENCING);
}
|
cmd_args background
PIPE pipeline{
        end_cmd(SEQUENCING_PIPE);
}
|
cmd_args background
OR pipeline{
        end_cmd(SEQUENCING_OR);
}
|
cmd_args background
AND pipeline{
        end_cmd(SEQUENCING_AND);
}
|
cmd_args background{
        end_cmd(SEQUENCING_NOTHING);
}
|;
cmd_args: WORD list_args params io_list{
        printdebug("YACC COMMMAND : %s\n", $1);
    add_arg($1);
};

list_args: OPTION list_args{
printdebug ("yacc list arg plusieurs: %s\n", $1);
add_arg($1);
}|OPTION{
printdebug ("yacc list arg seul : %s\n", $1);
add_arg($1);
}|;

params: WORD params{
printdebug ("yacc param plusieurs : %s\n", $1);
    add_arg($1);
}
|WORD {
printdebug ("yacc param seul: %s\n", $1);
    add_arg($1);
}|;
background: AMPERSAND{
        set_background();
}
|;

io_list: GREAT WORD{
    set_io(GREAT,$2);
}|GREAT_GREAT WORD{
    set_io(GREAT_GREAT,$2);
} LESS WORD{
    set_io(LESS,$2);
}| ERR_GREAT WORD{
    set_io(ERR_GREAT,$2);
}| ERR_GREAT_GREAT WORD{
    set_io(ERR_GREAT_GREAT,$2);
}| GREAT_AMP WORD{
    set_io(GREAT_AMP,$2);
}| GREAT_GREAT_AMP WORD{
    set_io(GREAT_GREAT_AMP,$2);
}|;

%%

struct CmdArg *temp;
void set_io(enum yytokentype tokentype, char* file){

}
void set_background() {
    temp->_background = 1;
}
void add_arg(char* s){
    if (!temp)temp = new_cmdArg();
    cmdarg_add_argument(temp,s);
    free(s);
}
void end_cmd(Sequencing seq){
    temp->_seq=seq;
    command_add_cmdArg(temp, seq);
    free_cmdArg(temp);
    temp = NULL;
}
</code>```

Thank you for your help.

答:
To add to @Oneill comment, the generated lex code provide global functions you can declare (with extern) and call to handle situations like this.  In your specific case, you are looking for the function int yylex_destroy ( void );.  When you call that function in your code, it will clear up any remaining memory allocated by the lexer.

Here are the list of functions:

```<code>int yylex_destroy ( void );
int yyget_debug ( void );
void yyset_debug ( int debug_flag  );
YY_EXTRA_TYPE yyget_extra ( void );
void yyset_extra ( YY_EXTRA_TYPE user_defined  );
FILE *yyget_in ( void );
void yyset_in  ( FILE * _in_str  );
FILE *yyget_out ( void );
void yyset_out  ( FILE * _out_str  );
int yyget_leng ( void );
char *yyget_text ( void );
int yyget_lineno ( void );
void yyset_lineno ( int _line_number  );
</code>```

ContentLicense: CC BY-SA 3.0

Title: Why yacc have memory leak at exit?

Body:
when I execute my lex/yacc program with valgrind, it find memory leak. But I would know if it's possible to delete this memory leak. The output of valgrind is:

==10006==
==10006== HEAP SUMMARY:
==10006==     in use at exit: 16,458 bytes in 3 blocks
==10006==   total heap usage: 13 allocs, 10 frees, 16,684 bytes allocated
==10006==
==10006== 8 bytes in 1 blocks are still reachable in loss record 1 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x402411: yyensure_buffer_stack (lex.yy.c:1552)
==10006==    by 0x400DA9: yylex (lex.yy.c:686)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== 64 bytes in 1 blocks are still reachable in loss record 2 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x401FA5: yy_create_buffer (lex.yy.c:1387)
==10006==    by 0x400DD3: yylex (lex.yy.c:688)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== 16,386 bytes in 1 blocks are still reachable in loss record 3 of 3
==10006==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10006==    by 0x4028FA: yyalloc (lex.yy.c:1852)
==10006==    by 0x401FDC: yy_create_buffer (lex.yy.c:1396)
==10006==    by 0x400DD3: yylex (lex.yy.c:688)
==10006==    by 0x40312D: yyparse (parser.tab.c:1183)
==10006==    by 0x40462F: parse (Parser.c:10)
==10006==    by 0x4045EB: main (main.c:21)
==10006==
==10006== LEAK SUMMARY:
==10006==    definitely lost: 0 bytes in 0 blocks
==10006==    indirectly lost: 0 bytes in 0 blocks
==10006==      possibly lost: 0 bytes in 0 blocks
==10006==    still reachable: 16,458 bytes in 3 blocks
==10006==         suppressed: 0 bytes in 0 blocks
==10006==
==10006== For counts of detected and suppressed errors, rerun with: -v
==10006== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

And my lex:

Chiffre [0-9]
Lettre [a-zA-Z]
Alphanum ({Chiffre}{Lettre})+

%{

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.tab.h"

%}
%%
-[a-zA-Z]+ {
yylval.
string = strdup(yytext);
    return OPTION;
}

[a-zA-Z0-9_\-./]+ {
    yylval.string = strdup(yytext);
    return WORD;
}
"||" {
return OR;
}
"|" {
return PIPE;
}
"&&" {
return AND;
}
"&" {
    return AMPERSAND;
}
";" {
return SEMICOLON;
}
"2>" {
return
ERR_GREAT;
}

">&" {
return
GREAT_AMP;
}

"2>>" {
return
ERR_GREAT_GREAT;
}
">>&" {
return
GREAT_GREAT_AMP;
}
">>" {
return
GREAT_GREAT;
}

">" {
return
GREAT;
}

"<" {
return
LESS;
}

[ \t]+ {
}

"\n" {
return 0;
}

%%

And my yacc file:

%{
#include <stdio.h>
#include "executor/CmdArg.h"
#include "executor/Command.h"
#include "print.h"
int yyerror(const char *msg) {
    return fprintf(stderr, "YACC: %s\n", msg);
}
%}

%union {
    int number;
    char *string;
};
%token<string> WORD
%token<string> OPTION
%destructor {
free($$);
} <string>
%token<void> SEMICOLON
%token OR AND PIPE AMPERSAND GREAT GREAT_GREAT LESS ERR_GREAT ERR_GREAT_GREAT GREAT_AMP GREAT_GREAT_AMP
%error-verbose
%%

pipeline: cmd_args
background SEMICOLON
pipeline{
end_cmd(SEQUENCING_SEQUENCING);
}
|
cmd_args background
PIPE pipeline{
        end_cmd(SEQUENCING_PIPE);
}
|
cmd_args background
OR pipeline{
        end_cmd(SEQUENCING_OR);
}
|
cmd_args background
AND pipeline{
        end_cmd(SEQUENCING_AND);
}
|
cmd_args background{
        end_cmd(SEQUENCING_NOTHING);
}
|;
cmd_args: WORD list_args params io_list{
        printdebug("YACC COMMMAND : %s\n", $1);
    add_arg($1);
};

list_args: OPTION list_args{
printdebug ("yacc list arg plusieurs: %s\n", $1);
add_arg($1);
}|OPTION{
printdebug ("yacc list arg seul : %s\n", $1);
add_arg($1);
}|;

params: WORD params{
printdebug ("yacc param plusieurs : %s\n", $1);
    add_arg($1);
}
|WORD {
printdebug ("yacc param seul: %s\n", $1);
    add_arg($1);
}|;
background: AMPERSAND{
        set_background();
}
|;

io_list: GREAT WORD{
    set_io(GREAT,$2);
}|GREAT_GREAT WORD{
    set_io(GREAT_GREAT,$2);
} LESS WORD{
    set_io(LESS,$2);
}| ERR_GREAT WORD{
    set_io(ERR_GREAT,$2);
}| ERR_GREAT_GREAT WORD{
    set_io(ERR_GREAT_GREAT,$2);
}| GREAT_AMP WORD{
    set_io(GREAT_AMP,$2);
}| GREAT_GREAT_AMP WORD{
    set_io(GREAT_GREAT_AMP,$2);
}|;

%%

struct CmdArg *temp;
void set_io(enum yytokentype tokentype, char* file){

}
void set_background() {
    temp->_background = 1;
}
void add_arg(char* s){
    if (!temp)temp = new_cmdArg();
    cmdarg_add_argument(temp,s);
    free(s);
}
void end_cmd(Sequencing seq){
    temp->_seq=seq;
    command_add_cmdArg(temp, seq);
    free_cmdArg(temp);
    temp = NULL;
}

Thank you for your help.

Body:
To add to @Oneill comment, the generated lex code provide global functions you can declare (with extern) and call to handle situations like this.  In your specific case, you are looking for the function int yylex_destroy ( void );.  When you call that function in your code, it will clear up any remaining memory allocated by the lexer.

Here are the list of functions:

int yylex_destroy ( void );
int yyget_debug ( void );
void yyset_debug ( int debug_flag  );
YY_EXTRA_TYPE yyget_extra ( void );
void yyset_extra ( YY_EXTRA_TYPE user_defined  );
FILE *yyget_in ( void );
void yyset_in  ( FILE * _in_str  );
FILE *yyget_out ( void );
void yyset_out  ( FILE * _out_str  );
int yyget_leng ( void );
char *yyget_text ( void );
int yyget_lineno ( void );
void yyset_lineno ( int _line_number  );

ContentLicense: CC BY-SA 4.0


问:
How can be transformed [EventLoopFuture<Type>] into EventLoopFuture<[Type]> in Vapor?
I try to transform [EventLoopFuture Type ] into EventLoopFuture<[Type]>.

Code example:

```<code>struct QuestionDTO2: Content {
  var text: String?
}

func getUserQuestions(req: Request) throws -> EventLoopFuture<[QuestionDTO2]> {
  let a = try req.content.decode(GetUserQuestions.self)
  return Question.query(on: req.db).all().flatMap {qs -> EventLoopFuture<[QuestionDTO2]> in
    return qs.map {q -> EventLoopFuture<QuestionDTO2> in
      QuestionDTO2(text: q.text)
    }
  }
}
</code>```

答:
func getUserQuestions(req: Request) throws -> EventLoopFuture<[QuestionDTO2]> {
    Question.query(on: req.db).all().map {
        $0.map { QuestionDTO2(text: $0.text) }
    }
}
```

You just have to replace flatMap with map cause next code doesn't return EventLoopFuture.

Body:
I try to transform [EventLoopFuture Type ] into EventLoopFuture<[Type]>.

Code example:

struct QuestionDTO2: Content {
  var text: String?
}

func getUserQuestions(req: Request) throws -> EventLoopFuture<[QuestionDTO2]> {
  let a = try req.content.decode(GetUserQuestions.self)
  return Question.query(on: req.db).all().flatMap {qs -> EventLoopFuture<[QuestionDTO2]> in
    return qs.map {q -> EventLoopFuture<QuestionDTO2> in
      QuestionDTO2(text: q.text)
    }
  }
}

Body:
func getUserQuestions(req: Request) throws -> EventLoopFuture<[QuestionDTO2]> {
    Question.query(on: req.db).all().map {
        $0.map { QuestionDTO2(text: $0.text) }
    }
}

You just have to replace flatMap with map cause next code doesn't return EventLoopFuture.


答:
Your dictionary does not map all characters to the ones you are expecting.

For example:

```<code>"ゎ" maps to "わ"
"τ"  maps to "て"
</code>```

You process replaces the result of previous mappings causing some of the mapped characters to be mapped again at the next iteration.

To avoid double translating you can convert your string like this:

```<code>mystr = "".join(mydict.get(c,c) for c in mystr)
</code>```

Which will result in:

```<code>きようわ、1人て"ててｶヽせて下さい。
</code>```

You will need to fix the letter mappings in the dictionary to obtain your desired result:

```<code>きょうは、1人で行かせて下さい。
</code>```

Title: Decode a text using a dictionary

Body:
I'm trying to decode a text by using this dictionary which will serve as alphabet:

mydict = {'ぁ': 'あ', 'ァ': 'あ', '了': 'あ', 'ぃ': 'い', 'ィ': 'い', 'ﾚヽ': 'い', 'ﾚ丶': 'い', 'レ）': 'い', 'ﾚ`': 'い', 'L丶': 'い', 'L1': 'い', 'ﾚl': 'い', 'ぅ': 'う', 'ゥ': 'う', '宀': 'う', 'ヴ': 'ふ', 'ウ': 'う',
'ぇ': 'え', 'ェ': 'え', '之': 'え', '工': 'I', 'ヱ': 'え', 'ぉ': 'を', 'ォ': 'お', '才': 'お', 'ｶゝ': 'か', 'ｶ丶': 'か', 'ｶヽ': 'か', 'ヵゝ': 'か', 'ｶ`': 'か', 'ｶゞ': 'か', 'カ': 'か', 'ヵゞ': 'が', 'カ゛':
'ガ', '力゛': 'ガ', '(ｷ': 'き', '(≠': 'き', 'L≠': 'き', 'ｷ':'き','‡': 'き',"(ｷ\"\"": "ぎ", "(≠\"": "ぎ", "L≠\"": "ぎ", "ｷ\"":"ぎ","‡\"": "ぎ", '＜': 'く', '〈': 'く', '勹': 'く', 'ヶ': 'け', '(ﾅ': 'け', 'ﾚ†': 'け', 'ﾚﾅ': 'け', '|ナ': 'け', 'l+': 'け', 'Iﾅ': 'け',"＜\"": "ぐ", "〈\"": "ぐ", "勹\"": "ぐ", "ヶ\"": "げ", "(ﾅ\"": "げ", "ﾚ†\"": "げ", "ﾚﾅ\"": "げ", "|ナ\"": "げ", "l+\"": "げ", "Iﾅ\"": "げ", '〓': 'こ', '=': 'こ', ']': 'こ', '⊃': 'こ', '⊇': 'こ',"〓\"": "ご", "=\"": "ご", "]\"": "ご", "⊃\"": "ご", "⊇\"": "ご", '廾': 'さ', '±': 'さ', '(十': 'さ', 'L+': 'さ', '(+': 'さ', '､ﾅ': 'さ', 'ι': 'し', '∪': 'U', 'U': 'し', '￡': 'す', 'ﾌ､': 'す', '世': 'せ', 'ξ': 'そ', 'ζ': 'ら', '`ﾉ': 'そ', '丶/': 'そ', 'ヽ丿': 'そ', 'ﾅ=': 'た', '+=': 'た', '†ﾆ': 'た', 'ﾅﾆ': 'た', '十こ': 'た', '†こ': 'た', 'ﾅ⊇': 'た', 'T=': 'た', '十=': 'た', '夕': 'た', '干': 'ち', '千': 'ち', '于': 'ち', 'ろ＋': 'ち', 'っ': 'つ', 'ッ': 'つ', 'ﾂ【っ】': 'つ', '廾"': 'ざ', '±"': 'ざ', '(十"': 'ざ', 'L+"': 'ざ', '(+"': 'ざ', '､ﾅ"': 'ざ', 'ι"': 'じ', '∪"': 'じ', 'U"': 'じ', '￡"': 'ず', 'ﾌ､"': 'ず', '世"': 'ぜ', 'ξ"': 'ぞ', 'ζ"': 'ぞ', '`ﾉ"': 'ぞ', '丶/"': 'ぞ', 'ヽ丿"': 'ぞ', 'ﾅ="': 'だ', '+="': 'だ', '†ﾆ"': 'だ', 'ﾅﾆ"': 'だ', '十こ"': 'だ', '†こ"': 'だ', 'ﾅ⊇"': 'だ', 'T="': 'だ', '十="': 'だ', '夕"': 'だ', 'っ"': 'づ', 'ッ"': 'づ', 'ﾂ【っ】"': 'づ', '⊃"':'づ','⊃':'つ','干"': 'ぢ', '千"': 'ぢ', '于"': 'ぢ', 'ろ＋"': 'ぢ','τ': 'て', '〒': 'て', 'z': 'て', '乙': 'て', '┠': 'と', '┝': 'と', '┣': 'と', '├': 'と', '`⊂': 'と', '卜': 'と', '`c': 'と',"τ\"": 'で', 'z"': 'で', '乙"': 'で', '┠"': 'ど', '┝"': 'ど', '┣"': 'ど', '├"': 'ど', '`⊂"': 'ど', '卜"': 'ど', '`c"': 'ど', 'ﾅょ': 'な', '十ょ': 'な', '†ょ': 'な', 'ﾅg': 'な', '†ょゝ': 'な', '十': 'な', '(ﾆ': 'に', '|=': 'に', '丨ﾆ': 'に', 'L=': 'に', 'I=': 'に', '（⊇': 'に',
'レこ': 'に', '(二': 'に', 'ﾚﾆ': 'に', 'йu': 'ぬ', 'ゐ': 'み', 'йё': 'ね', '/': 'の', '丿': 'の', 'σ': 'の', '⊂n': 'の', '＠': 'の', "'`": 'は', '八': 'は', 'l￡': 'は', '(￡': 'は', 'ﾉ|': 'は', 'ﾉl': 'は', 'ﾚ￡': 'は', 'ﾚよ': 'は', 'ﾊ〃': 'バ', 'ﾊo': 'パ', '匕': 'ひ', 'ﾋ〃': 'ビ', 'ﾋo': 'ピ', ',ζ,':
'ふ', 'ﾌ〃': 'ブ', 'ﾌo': 'プ', '〜': 'へ', '∧': 'へ', 'ﾍ〃': 'べ', 'ﾍo': 'ペ', '朮': 'ほ', 'ﾚま': 'ほ', 'ﾎ〃': 'ボ', 'ﾎo': 'ポ', 'ма': 'ま', 'мα': 'ま', '彡': 'み', '￡′': 'む', '厶': 'む', '×': 'め', 'x': 'め', 'χ': 'X', '乂': 'X', '〆': 'め', 'м○': 'も', 'мσ': 'も', '=し': 'も', '=L': 'も', 'ゃ':
'や', 'ャ': 'や', 'ゅ': 'ゆ', 'ュ': 'ゆ', 'ょ': 'よ', 'ョ': 'よ', '∋': 'よ', 'чo': 'よ', '∃': 'よ', 'яа': 'ら', 'b`': 'ら', 'L|': 'り', 'l)': 'り', 'ﾚ｣': 'り', 'ﾚ)': 'り', '┗』': 'り', '└丿': 'り', 'v)': 'り', '丶)': 'り', 'ゐ': 'る', 'ゑ': 'る', '儿': 'る', 'lﾚ': 'る', '｣レ': 'る', '｜ﾚ': 'る', 'ﾉﾚ': 'る', '/ﾚ': 'る', 'яё': 'れ', 'з': 'ろ', 'З': 'ろ', '回': '口', 'ゎ': 'わ', 'ヮ': 'わ', 'wα': 'わ', 'щo': 'を', 'ε': 'を', 'ω': 'ん', '冫': 'ん', 'w': 'ん', 'h': 'ん', 'ﾝ': 'ん', 'ｿ': 'ん', '〃': '濁点', '”': '濁点', '¨': '濁点', '→': 'ー', '⇒': 'ー', 'o': '。', '○': '。', 'まぢ': 'まじ', 'ッ塚': 'てゆうか', 'ッ乙ゆｳねぇ': 'て言っていて', '王見': '現', '禾斗': '科', '禾ﾑ': '私', 'ﾛ十': '叶', 'ﾃ殳': '役', 'ｲ歹ﾘ': '例', '辶斤': '近', 'ｲ廴聿': '健', 'ﾅ月': '有', 'ﾀ。': '名', '⊃i⊂': '氷', 'ﾗ|＜': '氷', '无': '天', '夲': '本', '來': '来', 'ﾈ申': '神', '走召': '超', '木木': '林', '木交': '校', '糸色': '絶', '糸及': '級', '金失': '鉄', '金矢': '鉄', '木市': '柿', 'ｲ子': '仔', '愛ιτゑ': '愛してる', '愛Uτゑ': '愛してる', '人㊥ょU': '仲良し', 'イ㊥夜歹ﾋ': '仲良し', '言身寸': '謝', '糸冬': '終', '文寸': '対', 'イ更戸斤': '便所', '木圭哥欠丈乙': '桂歌丸', '因': '大', '囚': '人', '困': '木', '圏': '巻', '圉': '幸', '囦': '水', '囝': '子', '囡': '女', '団': '寸', '囲': '井', '囮': '化', '园': '元', '図': '爪', '囨': '不', '固': '古', '囶': '八土', '国': '玉', '囹': '令', '4ほぅ圀': '四方八方', '囿': '有', '圕': '書', '圓': '員', '仲仔': '仲良し', 'Θ': '日', '曰': '日', 'Φ': '中', '㊥': '中', '升': 'チート', 'ﾃﾃ': '行', '〒〒': '行', '糸合米斗': '給料', '京尤シ舌': '就活', 'ｲ士': '仕', 'ｲ木': '休', 'ﾈ兄': '祝', '言売': '読', '谷欠': '欲', '原頁': '願', '月月': '朋', '言吾': '語', '言忍': '認', '糸売': '続', 'ｲ吏': '使', 'ﾀﾋ': '死', '㊤': '上', '㊦': '下', '㊧': '左', 'ﾅｪ': '左', '㊨': '右', '㊞': '印', 'E卩': '印', '闩': 'A', '月': 'A', 'Д': 'A', 'д': 'A', '＠': 'A', 'Å': 'A', '∀': 'A', '吕': 'B', '官': 'B', '♭': 'B', 'в': 'B', 'ь': 'B', '匚': 'C', '匸': 'C', '￠': 'C', '⊂': 'C', '℃': 'C', '囙': 'D', 'ヨ': 'E', '巨': 'E', '臣': 'E', '巳': 'E', 'ㅌ': 'E', 'ё': 'E', '孒': 'F', '下': 'F', '⊂┐': 'G', 'C┐': 'G', '丩': 'H', 'н': 'H', '｜': 'L', 'し': 'J', '」': 'J', '』': 'J', '|く': 'K', 'κ': 'K', '└': 'L', '从':
'M', 'ﾍﾍ': 'M', '川': 'M', '瓜': 'M', 'м': 'M', '冂': 'N', '∩': 'N', 'и': 'N', 'И': 'N', '口': 'O', '○': 'O', 'ο': 'O', '尸': 'P', 'ρ': 'P', '电': 'Q', 'O、': 'Q', '尺': 'R', 'γ': 'R', 'я': 'R', 'Я': 'R', '丂': 'S', '＄': 'S', '∫': 'S', '丁': 'T', 'て': 'T', '十': 'T', 'т': 'T', '凵': 'U', 'ц': 'U', 'レ': 'V', '∨': 'V', '山': 'W', 'ш': 'W', 'щ': 'W', 'Ш': 'W', 'Щ': 'W', '×': 'X', 'ソ': 'Y', '￥': 'Y', 'ч': 'Y', 'Ч': 'Y', '乙': 'Z'}

and i have this string:

mystr ="ｷょぅゎ、1囚τ\"〒〒ｶヽ世τ㊦±ぃ。"

to translate this text into correct japanese i use this code:

new_d = {}
for k in sorted(mydict, key=len, reverse=True):
    new_d[k] = mydict[k]
for el,it in new_d.items():
    if el in mystr:
        mystr = mystr.replace(el.strip(),new_d.get(el).strip())
    print(mystr.strip())

I get this string printed:

きようわ、1人T行かせTFさい。

whereas i should normally get

きょうは、1人で行かせて下さい。

Can somebody help me please, because i don't understand why it's not working.

Body:
Your dictionary does not map all characters to the ones you are expecting.

For example:

"ゎ" maps to "わ"
"τ"  maps to "て"

You process replaces the result of previous mappings causing some of the mapped characters to be mapped again at the next iteration.

To avoid double translating you can convert your string like this:

mystr = "".join(mydict.get(c,c) for c in mystr)

Which will result in:

きようわ、1人て"ててｶヽせて下さい。

You will need to fix the letter mappings in the dictionary to obtain your desired result:

きょうは、1人で行かせて下さい。


问:
Dynamic date selection with selenium using python
I am totally new to the selenium package a try to figure out how to get access to dynamic date events.
For example on the 10.02.2022 I want only to click on the event at 6.30 - 08.15. I am able to access to particular event with the "find_element_by_xpath" statement but this is just static.

Do you know a way to search in the class of "day has-event" at the data-date "10.02.2022" for the particular time slots as shown in the picture?

Thank you very much!

Classes

Class opened

答:
I think the best way to do that is first of all, find needed date column and than iterate through elements inside that to find time you want. Some code example here:

needed_time = '6.30 - 08.15'
date = page.find_element_by_css_selector('.day.has-event[data-date="10.02.2022"]')
events = date.find_elements_by_css_selector('ul li')
for event in events:
    time = event.find_element_by_css_selector('span').text
    if time == needed_time:
        break
else:
    event = None
    print("Needed time was not found!")
```