问:
How to fix the Jest Test using Mock Service Worker?

I want to test the React App function

```<code>import React from 'react'
import { useState, useEffect } from "react";

function App () {

    const [message, setMessage] = useState('')

    useEffect(() => {
           async function getMessage () {
             const url = process.env.REACT_APP_BACKEND_URL  +"/helloworld"
                console.log(url)
                try {
                      const headers = new Headers()
                            headers.append('Access-Control-Allow-Origin','*')
                      console.log(headers.get('Access-Control-Allow-Origin'))
                      const response = await fetch(url, {
                                       mode: 'cors',
                                       headers: {'Access-Control-Allow-Origin':'*'}
                                                        }
                                                   )
                      console.log(response.status)
                      console.log(response)
                      const text = await response.text()
                      console.log(text)
                       setMessage(text)
                    } catch(error){
                          console.log('fetch error')
                          console.error('There has been a problem with', error);
                    }
         }
  getMessage()
}, [])
    return ( <div>{message}</div>)
 }

export default  App ;
</code>```

with the Jets Test

```<code>import React from 'react'
import App from './App'
import {render,screen} from '@testing-library/react'

it('should display hello world', async () => {
     render(<App />);
     const linkElement = await screen.getByText('Hello World')
     expect(linkElement).toBeInTheDocument()
 })
</code>```

The fetch called is mocked with Mock Service Worker Handler

```<code>import { rest } from 'msw'

export const handlers = [
  rest.get(process.env.REACT_APP_BACKEND_URL+"/helloworld" , (reg, res, ctx ) => {
         console.log('mock get')
         console.log(process.env.REACT_APP_BACKEND_URL)
        return res(
           ctx.status(200),
           ctx.text("Hello World"),
           ctx.set({
                     'Access-Control-Allow-Origin':'*',
                     'Content-type':'text/plain'
                   })
    )
})
]
</code>```

Using the servere

```<code>// src/mocks/server.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'

// This configures a request mocking server with the given request handlers.
export const server = setupServer(...handlers)
</code>```

The server is setup in the file setUpTestJs

```<code>import '@testing-library/jest-dom'
import { server } from './mocks/server.js'

beforeAll(() => {  console.log("befor all server listen")
                   server.listen()
                }
          )
afterEach(() => {   console.log("after each server reset handlers ")
                    server.resetHandlers()
                }
         )
// Clean up after the tests are finished.
afterAll(() => {  console.log("after all  server closed")
                  server.close()
               }
         )
</code>```

The index.js looks like this

```<code>import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

if (process.env.REACT_APP_USE_MSW_MOCK_API === 'yes') { // eslint-disable-line
  const { worker } = require('./mocks/worker'); // eslint-disable-line
  worker.start();
  console.log("worker started")
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
</code>```

The package.json looks like this

```<code>{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.12.0",
    "@testing-library/react": "^11.2.7",
    "dotenv": "^10.0.0",
    "eslint-plugin-jest": "^24.3.6",
    "npm": "^7.24.2",
    "react": "^17.0.0",
    "react-async": "^10.0.1",
    "react-dom": "^17.0.0",
    "react-scripts": "^5.0.0",
    "snyk": "^1.639.0",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "start:msw": "REACT_APP_USE_MSW_MOCK_API=yes react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "docgen": "react-docgen src -e [src/*.test.js,src/setupTests.js,src/reportWebVitals.js,src/index.js ]",
    "lint": "eslint src",
    "auth": "snyk auth xxxxxxxxxxxx",
    "wizard": "snyk wizard",
    "snyk": "snyk test",
    "sonar": "sonar-scanner -Dsonar.host.url=https://sonarcloud.io/ -Dsonar.login= xxxxxxxxxxxx-Dsonar.organization=steinko-github -Dsonar.projectKey=frontend-CI-CD"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@testing-library/dom": "^8.11.1",
    "@testing-library/react-hooks": "^7.0.2",
    "@testing-library/user-event": "^13.5.0",
    "babel-eslint": "^10.1.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-testing-library": "^4.6.0",
    "jest-fetch-mock": "^3.0.3",
    "msw": "^0.36.4",
    "react-docgen": "^5.4.0",
    "sonarqube-scanner": "^2.8.1"
  },
  "msw": {
    "workerDirectory": "public"
  }
}
</code>```

When I run the test I het following result

```<code>console.log
    befor all server listen

      at src/setupTests.js:8:28

  console.log
    http://localhost:3000/helloworld

      at getMessage (src/App.jsx:11:25)

  console.log
    *

      at getMessage (src/App.jsx:15:31)

  console.log
    mock get

      at src/mocks/handlers.js:7:18

  console.log
    http://localhost:3000

      at src/mocks/handlers.js:8:18

  console.log
    after each server reset handlers

      at Object.<anonymous> (src/setupTests.js:14:29)

  console.log
    after all  server closed

      at src/setupTests.js:19:27

 FAIL  src/App.test.jsx
  ✕ should display hello world (117 ms)

  ● should display hello world

    TestingLibraryElementError: Unable to find an element with the text: Hello World. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

    <body>
      <div>
        <div />
      </div>
    </body>

      5 | it('should display hello world', async () => {
      6 |      render(<App />);
    > 7 |      const linkElement = await screen.getByText('Hello World')
        |                                       ^
      8 |      expect(linkElement).toBeInTheDocument()
      9 |  })

      at Object.getElementError (node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/config.js:37:19)
      at node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:90:38
      at node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:62:17
      at getByText (node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:111:19)
      at Object.<anonymous> (src/App.test.jsx:7:39)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        3.441 s
Ran all test suites related to changed files.

Watch Usage: Press w to show more.
</code>```

What must I do to run the test sucessfully

答:
Try using await screen.findByText('Hello World') instead.

getByText is synchronous, while your "Hello World" text comes from an API call (which response you rightfully mock). In other words, getBy* queries will throw immediately if their condition is not met.

Whenever you want to assert a UI that depends on the asynchronous state, use findBy*. Because otherwise what happens is that your test assertion runs before your component receives the response, so there's no response text yet rendered.

Also, a very good read on Queries in React Testing Library.

Body:
I want to test the React App function

import React from 'react'
import { useState, useEffect } from "react";

function App () {

    const [message, setMessage] = useState('')

    useEffect(() => {
           async function getMessage () {
             const url = process.env.REACT_APP_BACKEND_URL  +"/helloworld"
                console.log(url)
                try {
                      const headers = new Headers()
                            headers.append('Access-Control-Allow-Origin','*')
                      console.log(headers.get('Access-Control-Allow-Origin'))
                      const response = await fetch(url, {
                                       mode: 'cors',
                                       headers: {'Access-Control-Allow-Origin':'*'}
                                                        }
                                                   )
                      console.log(response.status)
                      console.log(response)
                      const text = await response.text()
                      console.log(text)
                       setMessage(text)
                    } catch(error){
                          console.log('fetch error')
                          console.error('There has been a problem with', error);
                    }
         }
  getMessage()
}, [])
    return (
{message}
)
 }

export default  App ;

with the Jets Test

import React from 'react'
import App from './App'
import {render,screen} from '@testing-library/react'

it('should display hello world', async () => {
     render(<App />);
     const linkElement = await screen.getByText('Hello World')
     expect(linkElement).toBeInTheDocument()
 })

The fetch called is mocked with Mock Service Worker Handler

import { rest } from 'msw'

export const handlers = [
  rest.get(process.env.REACT_APP_BACKEND_URL+"/helloworld" , (reg, res, ctx ) => {
         console.log('mock get')
         console.log(process.env.REACT_APP_BACKEND_URL)
        return res(
           ctx.status(200),
           ctx.text("Hello World"),
           ctx.set({
                     'Access-Control-Allow-Origin':'*',
                     'Content-type':'text/plain'
                   })
    )
})
]

Using the servere

// src/mocks/server.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'

// This configures a request mocking server with the given request handlers.
export const server = setupServer(...handlers)

The server is setup in the file setUpTestJs

import '@testing-library/jest-dom'
import { server } from './mocks/server.js'

beforeAll(() => {  console.log("befor all server listen")
                   server.listen()
                }
          )
afterEach(() => {   console.log("after each server reset handlers ")
                    server.resetHandlers()
                }
         )
// Clean up after the tests are finished.
afterAll(() => {  console.log("after all  server closed")
                  server.close()
               }
         )

The index.js looks like this

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

if (process.env.REACT_APP_USE_MSW_MOCK_API === 'yes') { // eslint-disable-line
  const { worker } = require('./mocks/worker'); // eslint-disable-line
  worker.start();
  console.log("worker started")
}

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

The package.json looks like this

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.12.0",
    "@testing-library/react": "^11.2.7",
    "dotenv": "^10.0.0",
    "eslint-plugin-jest": "^24.3.6",
    "npm": "^7.24.2",
    "react": "^17.0.0",
    "react-async": "^10.0.1",
    "react-dom": "^17.0.0",
    "react-scripts": "^5.0.0",
    "snyk": "^1.639.0",
    "web-vitals": "^1.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "start:msw": "REACT_APP_USE_MSW_MOCK_API=yes react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "docgen": "react-docgen src -e [src/*.test.js,src/setupTests.js,src/reportWebVitals.js,src/index.js ]",
    "lint": "eslint src",
    "auth": "snyk auth xxxxxxxxxxxx",
    "wizard": "snyk wizard",
    "snyk": "snyk test",
    "sonar": "sonar-scanner -Dsonar.host.url=https://sonarcloud.io/ -Dsonar.login= xxxxxxxxxxxx-Dsonar.organization=steinko-github -Dsonar.projectKey=frontend-CI-CD"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@testing-library/dom": "^8.11.1",
    "@testing-library/react-hooks": "^7.0.2",
    "@testing-library/user-event": "^13.5.0",
    "babel-eslint": "^10.1.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-testing-library": "^4.6.0",
    "jest-fetch-mock": "^3.0.3",
    "msw": "^0.36.4",
    "react-docgen": "^5.4.0",
    "sonarqube-scanner": "^2.8.1"
  },
  "msw": {
    "workerDirectory": "public"
  }
}

When I run the test I het following result

console.log
    befor all server listen

      at src/setupTests.js:8:28

  console.log
    http://localhost:3000/helloworld

      at getMessage (src/App.jsx:11:25)

  console.log
    *

      at getMessage (src/App.jsx:15:31)

  console.log
    mock get

      at src/mocks/handlers.js:7:18

  console.log
    http://localhost:3000

      at src/mocks/handlers.js:8:18

  console.log
    after each server reset handlers

      at Object.<anonymous> (src/setupTests.js:14:29)

  console.log
    after all  server closed

      at src/setupTests.js:19:27

 FAIL  src/App.test.jsx
  ✕ should display hello world (117 ms)

  ● should display hello world

    TestingLibraryElementError: Unable to find an element with the text: Hello World. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

      5 | it('should display hello world', async () => {
      6 |      render(<App />);
    > 7 |      const linkElement = await screen.getByText('Hello World')
        |                                       ^
      8 |      expect(linkElement).toBeInTheDocument()
      9 |  })

      at Object.getElementError (node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/config.js:37:19)
      at node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:90:38
      at node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:62:17
      at getByText (node_modules/@testing-library/react/node_modules/@testing-library/dom/dist/query-helpers.js:111:19)
      at Object.<anonymous> (src/App.test.jsx:7:39)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        3.441 s
Ran all test suites related to changed files.

Watch Usage: Press w to show more.

What must I do to run the test sucessfully


来源: stackexchange

问:
How can I make a Java method accept arrays of different (primitive) variable types?
I want to write a simple method to print an array - looking like an array -  with its elements in the terminal, independent of whether it is an int[], boolean[], String[], double[] etc.

The String info parameter is just meant to output some answer phrase with the array shown, like "The wanted array is { .... }".

I am aware that in Java

unspecified parameter types should be handled with extreme care

primitive variable types cannot easily be used with generic data types

the usual answer for accepting different parameter types is overloading (which I finally did),

but the only difference between the different versions of the method printArray(...) is the variable type of the array handed over in the parameter list.

I also tried to hand over an object[] pArray as a parameter, but then it would only accept integer arrays, or give a runtime error message.

A similar concept is addressed in the answers to the former post Parameter For All Primitive Types of Java?, but - although it is pretty much the same question - the answers don't give solutions for arrays of simple primitives. They only answer

ways to find out, which parameter type was used, or

are limited to object types (including wrapper classes) or Number-objects, but which both don't solve my problem.

Looking at this the mantra "avoid code duplication" seems to be so obviously violated that I believe there must be a better solution.

Can anyone help me with this?    Here is the code:

```<code>void printArray(String info, boolean[] pArray)
{
    String arrayString = "";

    if (pArray.length > 0){
        arrayString = "{ " + pArray[0];

        for (int a = 1; a < pArray.length; a++){
            arrayString = arrayString + ", " + pArray[a];
        }
        arrayString = arrayString + " }";
    } else {
        arrayString = "{}";
    }

    System.out.println(info + arrayString + "\n");
}

void printArray(String info, int[] pArray)
{
    String arrayString = "";

    if (pArray.length > 0){
        arrayString = "{ " + pArray[0];

        for (int a = 1; a < pArray.length; a++){
            arrayString = arrayString + ", " + pArray[a];
        }
        arrayString = arrayString + " }";
    } else {
        arrayString = "{}";
    }

    System.out.println(info + arrayString + "\n");
}
</code>```

答:
Yes. But the only common ancestral type for all arrays1 is Object. You can use that and java.lang.reflect.Array. Also since printArray has no state, you might as well make it static like

```<code>static void printArray(String info, Object pArray) {
    StringBuilder sb = new StringBuilder(info);
    int len = Array.getLength(pArray);
    if (len > 0) {
        sb.append("{ ").append(Array.get(pArray, 0));
        for (int a = 1; a < len; a++) {
            sb.append(", ").append(Array.get(pArray, a));
        }
        sb.append(" }");
    } else {
        sb.append("{}");
    }
    System.out.println(sb);
}
</code>```

I tested it like

```<code>public static void main(String[] args) {
    boolean[] bArr = { true, true, false, false };
    int[] iArr = { 0, 1, 2, 3 };
    printArray("boolean[]", bArr);
    printArray("int[]", iArr);
}
</code>```

Which outputs

```<code>boolean[]{ true, true, false, false }
int[]{ 0, 1, 2, 3 }
</code>```

1Both primitive and reference types. Object obj = new int[] { 1, 2, 3 }; and Object obj = new String[] { "Hello", "World" }; are both valid. All arrays are Objects in Java.

ContentLicense: CC BY-SA 4.0

Body:
I want to write a simple method to print an array - looking like an array -  with its elements in the terminal, independent of whether it is an int[], boolean[], String[], double[] etc.

The String info parameter is just meant to output some answer phrase with the array shown, like "The wanted array is { .... }".

I am aware that in Java

unspecified parameter types should be handled with extreme care

primitive variable types cannot easily be used with generic data types

the usual answer for accepting different parameter types is overloading (which I finally did),

but the only difference between the different versions of the method printArray(...) is the variable type of the array handed over in the parameter list.

I also tried to hand over an object[] pArray as a parameter, but then it would only accept integer arrays, or give a runtime error message.

A similar concept is addressed in the answers to the former post Parameter For All Primitive Types of Java?, but - although it is pretty much the same question - the answers don't give solutions for arrays of simple primitives. They only answer

ways to find out, which parameter type was used, or

are limited to object types (including wrapper classes) or Number-objects, but which both don't solve my problem.

Looking at this the mantra "avoid code duplication" seems to be so obviously violated that I believe there must be a better solution.

Can anyone help me with this?    Here is the code:

void printArray(String info, boolean[] pArray)
{
    String arrayString = "";

    if (pArray.length > 0){
        arrayString = "{ " + pArray[0];

        for (int a = 1; a < pArray.length; a++){
            arrayString = arrayString + ", " + pArray[a];
        }
        arrayString = arrayString + " }";
    } else {
        arrayString = "{}";
    }

    System.out.println(info + arrayString + "\n");
}

void printArray(String info, int[] pArray)
{
    String arrayString = "";

    if (pArray.length > 0){
        arrayString = "{ " + pArray[0];

        for (int a = 1; a < pArray.length; a++){
            arrayString = arrayString + ", " + pArray[a];
        }
        arrayString = arrayString + " }";
    } else {
        arrayString = "{}";
    }

    System.out.println(info + arrayString + "\n");
}

Body:
Yes. But the only common ancestral type for all arrays1 is Object. You can use that and java.lang.reflect.Array. Also since printArray has no state, you might as well make it static like

static void printArray(String info, Object pArray) {
    StringBuilder sb = new StringBuilder(info);
    int len = Array.getLength(pArray);
    if (len > 0) {
        sb.append("{ ").append(Array.get(pArray, 0));
        for (int a = 1; a < len; a++) {
            sb.append(", ").append(Array.get(pArray, a));
        }
        sb.append(" }");
    } else {
        sb.append("{}");
    }
    System.out.println(sb);
}

I tested it like

public static void main(String[] args) {
    boolean[] bArr = { true, true, false, false };
    int[] iArr = { 0, 1, 2, 3 };
    printArray("boolean[]", bArr);
    printArray("int[]", iArr);
}

Which outputs

boolean[]{ true, true, false, false }
int[]{ 0, 1, 2, 3 }

1Both primitive and reference types. Object obj = new int[] { 1, 2, 3 }; and Object obj = new String[] { "Hello", "World" }; are both valid. All arrays are Objects in Java.


问:
After updating android studio, and WSL I can't connect expo to emulator
I recently updated android studio, and WSL from WSL1 to WSL2. I tried running expo start which works, until I try to open the app on my emulator which is running already. Then I get this error.

Obviously there is a connectivity problem between expo and the emulator, I am just not sure what I need to do.

Anyone know if there is any new changes with the new android release, or something else I am doing wrong?

答: The problem was with WSL2. After downgrading back to WSL1 I was able to connect to the android emulator.</p>


问:
Create an image in tkinter with just image data?
I'm trying to create an image in tkinter but I want to use the image data instead of passing in a file. How do I do that? Here's how I'm creating an image.

```<code>from tkinter import *

root = Tk()

global myimage
myimage = PhotoImage(data="IMAGE DATA HERE")

mytext = Text(root, width=100, height=50, )
mytext.pack()

mytext.image_create(END, image=myimage)

root.mainloop()
</code>```

When using this method i get an error saying that could not recognize image data

Quick note I used a python script to convert the image into bytes.

here is the data:

```<code>[encoded data, 10499 characters]
</code>```

答:
Your code is fine. The problem is the data, just like what the error is telling you. The original format of your data is jpeg, and tkinter doesn't natively support jpeg.

You will need to either convert the original image to GIF or PNG before encoding it, or use pillow to convert it before handing it off to tkinter.

Body:
I'm trying to create an image in tkinter but I want to use the image data instead of passing in a file. How do I do that? Here's how I'm creating an image.

from tkinter import *

root = Tk()

global myimage
myimage = PhotoImage(data="IMAGE DATA HERE")

mytext = Text(root, width=100, height=50, )
mytext.pack()

mytext.image_create(END, image=myimage)

root.mainloop()

When using this method i get an error saying that could not recognize image data

Quick note I used a python script to convert the image into bytes.

here is the data:

[encoded data, 10499 characters]


问:
Next auth v4 with Next.js middleware
I'm using Next.js with next auth v4 for authentication with credentials.

What I want to do is add a global verification for my API calls in a middleware to test before API calls the session. If the session is not null the call have to passed successfully, else if the session is null then handle an unauthorized error message and redirect to login page.

I wanna also add protected route and unprotected routes for login page and other pages that is not necessary to check authentication on it.

Here is my code:
[...nextauth].js

```<code>import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";
import api from './api'

export default NextAuth({
    providers: [
        CredentialsProvider({
          name: "Credentials",
          async authorize(credentials, req) {
            const {username,password} = credentials
            const user = await api.auth({
                username,
                password,
            })

            if (user) {
              return user
            } else {
              return null

            }
          }
        })
    ],
    callbacks: {
        async jwt({ token, user, account }) {
            let success = user?.id > 0
            if (account && success) {
                return {
                ...token,
                user : user ,
                accessToken: user.id
              };
            }
            return token;
        },

        async session({ session, token }) {
          session.user = token;
          return session;
        },
      },
    secret: "test",
    jwt: {
        secret: "test",
        encryption: true,
    },
    pages: {
        signIn: "/Login",
    },
})
</code>```

My _middleware.js

```<code>import { getSession } from "next-auth/react"
import { NextResponse } from "next/server"

/** @param {import("next/server").NextRequest} req */

export async function middleware(req) {
  // return early if url isn't supposed to be protected
   // Doesn't work here
  if (req.url.includes("/Login")) {
    return NextResponse.next()
  }

  const session = await getSession({req})
  // You could also check for any property on the session object,
  // like role === "admin" or name === "John Doe", etc.
  if (!session) return NextResponse.redirect("/Login")

  // If user is authenticated, continue.
  return NextResponse.next()
}
</code>```

答:
I would like to mention that those techniques can be improved depending on the situation and can be also migrated to TypeScript, which I'm going to follow up with a future edit, hope this might help.

I made it work by having the following:

FILE:  pages/admin/_middleware.js

NOTE: The middleware file can be individually set in paths, for more check please check the execution order

import { withAuth } from "next-auth/middleware"

export default withAuth({
  callbacks: {
    authorized: ({ token }) => token?.userRole === "admin",
  },
})
```
<p><strong>FILE:</strong> <code>api/auth/[...nextauth].js</code></p>
<pre class="lang-js prettyprint-override"><code>import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: "Username", type: "text", placeholder: "jsmith" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials, req) {
        const res = await fetch("http://localhost:3000/api/auth/getuser", {
          method: 'POST',
          body: JSON.stringify(credentials),
          headers: { "Content-Type": "application/json" }
        })
        const user = await res.json()

        // If no error and we have user data, return it
        if (res.ok && user) {
          return user;
        }
        return null
      }
    })
  ],
  secret: process.env.JWT_SECRET,
  callbacks: {
    async jwt({token, user, account}) {
      if (token || user) {
        token.userRole = "admin";
        return {...token};
      }
    },
  },
})
</code>```

FILE: api/auth/getuser.js

//YOUR OWN DATABASE
import { sql_query } from '@project/utils/db';

export default async function handler(req,res) {
  let username = req.body.username;
  let password = req.body.password;

  let isJSON = req.headers['content-type'] == "application/json";
  let isPOST = req.method === "POST";

  let fieldsExisting = password && username;

  if (isPOST && isJSON && fieldsExisting) {
    const { createHmac } = await import('crypto');

//This will require to have password field in database set as md5
//you can also have it as simple STRING, depends on preferences
    const hash = createHmac('md5', password ).digest('hex');

//YOUR OWN DATABASE
    const query = `SELECT * FROM users WHERE email='${username}' AND password='${hash}' LIMIT 1;`;

    let results = await sql_query(query);
    if (results == undefined) {
      res.status(404).json({ "error": "Not found" });
    } else {
      res.status(200).json({ "username": results[0].nume });
    }
  } else {
    res.status(500).json({ "error": "Invalid request type" });
  }
}
```
<p>That <code>//YOUR OWN DATABASE</code> for <strong>FILE:</strong> <code>utils/db</code>:</p>
<pre class="lang-js prettyprint-override"><code>import mysql from "serverless-mysql";

export const db = mysql({
  config: {
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USERNAME,
    password: process.env.MYSQL_PASSWORD,
  },
});

export async function sql_query(query_string values = []) {
  try {
    const results = await db.query(query_string, values);
    await db.end();
    return results;
  } catch (e) {
    if (typeof e === "string") {
      e.toUpperCase() // works, `e` narrowed to string
    } else if (e instanceof Error) {
      e.message // works, `e` narrowed to Error
    }
  }
}

</code>```

FILE: .env -- NOTE: CHANGE .env variables with your own

```<code>NEXTAUTH_URL=http://localhost:3000
MYSQL_HOST="0.0.0.0"
MYSQL_DATABASE="randomNAME"
MYSQL_USERNAME="randomNAME"
MYSQL_PASSWORD="randomPASS"
NEXTAUTH_SECRET="49dc52e6bf2abe5ef6e2bb5b0f1ee2d765b922ae6cc8b95d39dc06c21c848f8c"
JWT_SECRET="49dc52e6bf2abe5ef6e2bb5b0f1ee2d765b922ae6cc8b95d39dc06c21c848f8c"
</code>```

FILE: package.json

{
  "name": "MyAwesomeName",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "12.0.9",
    "next-auth": "^4.2.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "serverless-mysql": "^1.5.4",
    "swr": "^0.4.2"
  },
  "devDependencies": {
    "@types/node": "17.0.12",
    "@types/react": "17.0.38",
    "eslint": "8.7.0",
    "eslint-config-next": "12.0.9",
    "typescript": "4.5.5"
  }
}
```
<p><strong>EDIT: 01/07/2022 for NextJS 12.2.0 middleware</strong><br>
As I've mentioned, I will follow up with an edit for <strong>TypeScript</strong>, and was perfectly timed with 12.2.0 release for NextJS.<br>
I would also like to metion that:</p>
<p>Based on the discussion with a user in GitHub, apparently jose library works better while running Edge functions in the middleware while jsonwebtoken does not. This was based on SO question.<br>
The files should be the following:</p>
<p><strong>/package.json</strong></p>
<pre class="lang-json prettyprint-override"><code>{
  "name": "xyz123",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/react": "^11.9.3",
    "@emotion/styled": "^11.9.3",
    "@mui/material": "^5.8.6",
    "@prisma/client": "^4.0.0",
    "axios": "^0.27.2",
    "jose": "^4.8.3",
    "next": "12.2.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.33.0"
  },
  "devDependencies": {
    "@types/node": "18.0.0",
    "@types/react": "18.0.14",
    "@types/react-dom": "18.0.5",
    "eslint": "8.18.0",
    "eslint-config-next": "12.2.0",
    "prisma": "^4.0.0",
    "typescript": "4.7.4"
  }
}

</code>```

/pages/_middleware has been moved to /middleware, basically in the root folder, whe are going to have the following:

/middleware.ts

import { NextResponse } from "next/server";
import type { NextRequest } from 'next/server'
import { verify } from "./services/jwt_sign_verify";

const secret = process.env.SECRET || "secret";

export default async function middleware(req: NextRequest) {
  const jwt = req.cookies.get("OutsiteJWT");
  const url = req.url;
  const {pathname} = req.nextUrl;

  if (pathname.startsWith("/dashboard")) {
    if (jwt === undefined) {
      req.nextUrl.pathname = "/login";
      return NextResponse.redirect(req.nextUrl);
    }

    try {
      await verify(jwt, secret);
      return NextResponse.next();
    } catch (error) {
      req.nextUrl.pathname = "/login";
      return NextResponse.redirect(req.nextUrl);
    }
  }

  return NextResponse.next();
}
```
<p><strong>/services/jwt_sign_verify.ts</strong></p>
<pre class="lang-ts prettyprint-override"><code>import { SignJWT, jwtVerify, type JWTPayload } from 'jose';
import { Token } from "@typescript-eslint/types/dist/generated/ast-spec";

export async function sign(payload: string, secret: string): Promise<string> {
    const iat = Math.floor(Date.now() / 1000);
    const exp = iat + 60 * 60; // one hour

    return new SignJWT({ payload })
        .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
        .setExpirationTime(exp)
        .setIssuedAt(iat)
        .setNotBefore(iat)
        .sign(new TextEncoder().encode(secret));
}

export async function verify(token: string, secret: string): Promise<JWTPayload> {
    const { payload } = await jwtVerify(token, new TextEncoder().encode(secret));
    // run some checks on the returned payload, perhaps you expect some specific values

    // if its all good, return it, or perhaps just return a boolean
    return payload;
}
</code>```

/pages/api/auth/login.ts

/* eslint-disable import/no-anonymous-default-export */
import { serialize } from "cookie";
import { sign } from "../../../services/jwt_sign_verify";

const secret = process.env.SECRET || "secret";

export default async function (req, res) {
    const { username, password } = req.body;

// Check-in the database for a match,
//serialize and check your data before doing any operations.
//This IF statement is for checking demo purposes only.
    if (username === "Admin" && password === "Admin") {
        const token = await sign(
            "testing", //do some magic here
            secret
        );

        const serialised = serialize("OursiteJWT", token, {
            httpOnly: true,
            secure: process.env.NODE_ENV !== "development",
            sameSite: "strict",
            maxAge: 60 * 60 * 24 * 30,
            path: "/",
        });

        res.setHeader("Set-Cookie", serialised);

        res.status(200).json({ message: "Success!" });
    } else {
        res.status(401).json({ message: "Invalid credentials!" });
    }
}
```

Title: Next auth v4 with Next.js middleware

Body:
I'm using Next.js with next auth v4 for authentication with credentials.

What I want to do is add a global verification for my API calls in a middleware to test before API calls the session. If the session is not null the call have to passed successfully, else if the session is null then handle an unauthorized error message and redirect to login page.

I wanna also add protected route and unprotected routes for login page and other pages that is not necessary to check authentication on it.

Here is my code:
[...nextauth].js

import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";
import api from './api'

export default NextAuth({
    providers: [
        CredentialsProvider({
          name: "Credentials",
          async authorize(credentials, req) {
            const {username,password} = credentials
            const user = await api.auth({
                username,
                password,
            })

            if (user) {
              return user
            } else {
              return null

            }
          }
        })
    ],
    callbacks: {
        async jwt({ token, user, account }) {
            let success = user?.id > 0
            if (account && success) {
                return {
                ...token,
                user : user ,
                accessToken: user.id
              };
            }
            return token;
        },

        async session({ session, token }) {
          session.user = token;
          return session;
        },
      },
    secret: "test",
    jwt: {
        secret: "test",
        encryption: true,
    },
    pages: {
        signIn: "/Login",
    },
})

My _middleware.js

import { getSession } from "next-auth/react"
import { NextResponse } from "next/server"

/** @param {import("next/server").NextRequest} req */

export async function middleware(req) {
  // return early if url isn't supposed to be protected
   // Doesn't work here
  if (req.url.includes("/Login")) {
    return NextResponse.next()
  }

  const session = await getSession({req})
  // You could also check for any property on the session object,
  // like role === "admin" or name === "John Doe", etc.
  if (!session) return NextResponse.redirect("/Login")

  // If user is authenticated, continue.
  return NextResponse.next()
}

Body:
I would like to mention that those techniques can be improved depending on the situation and can be also migrated to TypeScript, which I'm going to follow up with a future edit, hope this might help.

I made it work by having the following:

FILE:  pages/admin/_middleware.js

NOTE: The middleware file can be individually set in paths, for more check please check the execution order

import { withAuth } from "next-auth/middleware"

export default withAuth({
  callbacks: {
    authorized: ({ token }) => token?.userRole === "admin",
  },
})

FILE: api/auth/[...nextauth].js

import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";

export default NextAuth({
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: "Username", type: "text", placeholder: "jsmith" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials, req) {
        const res = await fetch("http://localhost:3000/api/auth/getuser", {
          method: 'POST',
          body: JSON.stringify(credentials),
          headers: { "Content-Type": "application/json" }
        })
        const user = await res.json()

        // If no error and we have user data, return it
        if (res.ok && user) {
          return user;
        }
        return null
      }
    })
  ],
  secret: process.env.JWT_SECRET,
  callbacks: {
    async jwt({token, user, account}) {
      if (token || user) {
        token.userRole = "admin";
        return {...token};
      }
    },
  },
})

FILE: api/auth/getuser.js

//YOUR OWN DATABASE
import { sql_query } from '@project/utils/db';

export default async function handler(req,res) {
  let username = req.body.username;
  let password = req.body.password;

  let isJSON = req.headers['content-type'] == "application/json";
  let isPOST = req.method === "POST";

  let fieldsExisting = password && username;

  if (isPOST && isJSON && fieldsExisting) {
    const { createHmac } = await import('crypto');

//This will require to have password field in database set as md5
//you can also have it as simple STRING, depends on preferences
    const hash = createHmac('md5', password ).digest('hex');

//YOUR OWN DATABASE
    const query = `SELECT * FROM users WHERE email='${username}' AND password='${hash}' LIMIT 1;`;

    let results = await sql_query(query);
    if (results == undefined) {
      res.status(404).json({ "error": "Not found" });
    } else {
      res.status(200).json({ "username": results[0].nume });
    }
  } else {
    res.status(500).json({ "error": "Invalid request type" });
  }
}

That //YOUR OWN DATABASE for FILE: utils/db:

import mysql from "serverless-mysql";

export const db = mysql({
  config: {
    host: process.env.MYSQL_HOST,
    database: process.env.MYSQL_DATABASE,
    user: process.env.MYSQL_USERNAME,
    password: process.env.MYSQL_PASSWORD,
  },
});

export async function sql_query(query_string values = []) {
  try {
    const results = await db.query(query_string, values);
    await db.end();
    return results;
  } catch (e) {
    if (typeof e === "string") {
      e.toUpperCase() // works, `e` narrowed to string
    } else if (e instanceof Error) {
      e.message // works, `e` narrowed to Error
    }
  }
}

FILE: .env -- NOTE: CHANGE .env variables with your own

NEXTAUTH_URL=http://localhost:3000
MYSQL_HOST="0.0.0.0"
MYSQL_DATABASE="randomNAME"
MYSQL_USERNAME="randomNAME"
MYSQL_PASSWORD="randomPASS"
NEXTAUTH_SECRET="49dc52e6bf2abe5ef6e2bb5b0f1ee2d765b922ae6cc8b95d39dc06c21c848f8c"
JWT_SECRET="49dc52e6bf2abe5ef6e2bb5b0f1ee2d765b922ae6cc8b95d39dc06c21c848f8c"

FILE: package.json

{
  "name": "MyAwesomeName",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "12.0.9",
    "next-auth": "^4.2.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "serverless-mysql": "^1.5.4",
    "swr": "^0.4.2"
  },
  "devDependencies": {
    "@types/node": "17.0.12",
    "@types/react": "17.0.38",
    "eslint": "8.7.0",
    "eslint-config-next": "12.0.9",
    "typescript": "4.5.5"
  }
}

EDIT: 01/07/2022 for NextJS 12.2.0 middleware

As I've mentioned, I will follow up with an edit for TypeScript, and was perfectly timed with 12.2.0 release for NextJS.

I would also like to metion that:

Based on the discussion with a user in GitHub, apparently jose library works better while running Edge functions in the middleware while jsonwebtoken does not. This was based on SO question.

The files should be the following:

/package.json

{
  "name": "xyz123",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/react": "^11.9.3",
    "@emotion/styled": "^11.9.3",
    "@mui/material": "^5.8.6",
    "@prisma/client": "^4.0.0",
    "axios": "^0.27.2",
    "jose": "^4.8.3",
    "next": "12.2.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.33.0"
  },
  "devDependencies": {
    "@types/node": "18.0.0",
    "@types/react": "18.0.14",
    "@types/react-dom": "18.0.5",
    "eslint": "8.18.0",
    "eslint-config-next": "12.2.0",
    "prisma": "^4.0.0",
    "typescript": "4.7.4"
  }
}

/pages/_middleware has been moved to /middleware, basically in the root folder, whe are going to have the following:

/middleware.ts

import { NextResponse } from "next/server";
import type { NextRequest } from 'next/server'
import { verify } from "./services/jwt_sign_verify";

const secret = process.env.SECRET || "secret";

export default async function middleware(req: NextRequest) {
  const jwt = req.cookies.get("OutsiteJWT");
  const url = req.url;
  const {pathname} = req.nextUrl;

  if (pathname.startsWith("/dashboard")) {
    if (jwt === undefined) {
      req.nextUrl.pathname = "/login";
      return NextResponse.redirect(req.nextUrl);
    }

    try {
      await verify(jwt, secret);
      return NextResponse.next();
    } catch (error) {
      req.nextUrl.pathname = "/login";
      return NextResponse.redirect(req.nextUrl);
    }
  }

  return NextResponse.next();
}

/services/jwt_sign_verify.ts

import { SignJWT, jwtVerify, type JWTPayload } from 'jose';
import { Token } from "@typescript-eslint/types/dist/generated/ast-spec";

export async function sign(payload: string, secret: string): Promise<string> {
    const iat = Math.floor(Date.now() / 1000);
    const exp = iat + 60 * 60; // one hour

    return new SignJWT({ payload })
        .setProtectedHeader({ alg: 'HS256', typ: 'JWT' })
        .setExpirationTime(exp)
        .setIssuedAt(iat)
        .setNotBefore(iat)
        .sign(new TextEncoder().encode(secret));
}

export async function verify(token: string, secret: string): Promise<JWTPayload> {
    const { payload } = await jwtVerify(token, new TextEncoder().encode(secret));
    // run some checks on the returned payload, perhaps you expect some specific values

    // if its all good, return it, or perhaps just return a boolean
    return payload;
}

/pages/api/auth/login.ts

/* eslint-disable import/no-anonymous-default-export */
import { serialize } from "cookie";
import { sign } from "../../../services/jwt_sign_verify";

const secret = process.env.SECRET || "secret";

export default async function (req, res) {
    const { username, password } = req.body;

// Check-in the database for a match,
//serialize and check your data before doing any operations.
//This IF statement is for checking demo purposes only.
    if (username === "Admin" && password === "Admin") {
        const token = await sign(
            "testing", //do some magic here
            secret
        );

        const serialised = serialize("OursiteJWT", token, {
            httpOnly: true,
            secure: process.env.NODE_ENV !== "development",
            sameSite: "strict",
            maxAge: 60 * 60 * 24 * 30,
            path: "/",
        });

        res.setHeader("Set-Cookie", serialised);

        res.status(200).json({ message: "Success!" });
    } else {
        res.status(401).json({ message: "Invalid credentials!" });
    }
}


问:
Stripping whitespace in python
I'm reading the python crash course book. The author talks about stripping whitespace, and how to eliminate them in strings:

He gives an example like this:

```<code>favorite_language='python '
print(favorite_language.rstrip())

-- 'python'
</code>```

You can see the the whitespace is gone. Whenever I try it in sublime it gives me the first string ('python ') with extra whitespace.

答:
rstrip(): returns a new string with trailing whitespace removed. It’s
easier to remember as removing white spaces from “right” side of the
string.

please visit this site regarding formatting string in python.

```<code>#!/usr/bin/env python3.10
favorite_language=' python language '

print("."+favorite_language.rstrip()+".")#removes trailing white spaces
print("."+favorite_language.strip()+".")#removes white spaces from both leading and trailing
print("."+favorite_language.lstrip()+".")#removes ending white spaces
</code>```

output:

```<code>$ python3.10 myClass.py
. python language.
.python language.
.python language .
</code>```

Title: Stripping whitespace in python

Body:
I'm reading the python crash course book. The author talks about stripping whitespace, and how to eliminate them in strings:

He gives an example like this:

favorite_language='python '
print(favorite_language.rstrip())

-- 'python'

You can see the the whitespace is gone. Whenever I try it in sublime it gives me the first string ('python ') with extra whitespace.

Body:
rstrip(): returns a new string with trailing whitespace removed. It’s
easier to remember as removing white spaces from “right” side of the
string.

please visit this site regarding formatting string in python.

#!/usr/bin/env python3.10
favorite_language=' python language '

print("."+favorite_language.rstrip()+".")#removes trailing white spaces
print("."+favorite_language.strip()+".")#removes white spaces from both leading and trailing
print("."+favorite_language.lstrip()+".")#removes ending white spaces

output:

$ python3.10 myClass.py
. python language.
.python language.
.python language .


问:
Wordpress: Is there a way to adjust the Column Width for the Post table?
None of the suggested topics about width concern WordPress. What I need is a way to adjust the width of the Posts table which comes up when Posts is selected (Title Author Categories, etc.) I've looked in Appearance/Edit at every .php Template and can't find anything relating to this. I'm sure I've missed something. Also, I have no immediate need for the "Date" and "Tags" columns. Can I either delete these or least hide them?

Thanks,
Mike Carter

答:
The default table view provided by edit.php (e.g. for Posts/Pages/Events) looks really terrible in narrower viewports because the stylesheet includes fixed width table formatting:

You can shrink the menu away, remove columns from the table, or re-define the style as not fixed:

table.wp-list-table.fixed {
   table-layout: auto !important;
}
```

For a permanent solution, save the above rule in a user-defined stylesheet that gets applied to each page (e.g. using a browser extension such as Stylus).

ContentLicense: CC BY-SA 2.5

Body:
The default table view provided by edit.php (e.g. for Posts/Pages/Events) looks really terrible in narrower viewports because the stylesheet includes fixed width table formatting:

You can shrink the menu away, remove columns from the table, or re-define the style as not fixed:

table.wp-list-table.fixed {
   table-layout: auto !important;
}

For a permanent solution, save the above rule in a user-defined stylesheet that gets applied to each page (e.g. using a browser extension such as Stylus).


问:
Vue.js. Send get/post request with headers and parameners
All I want is to create LinkedIn login component. I cannot find any information about headers and parameters. Can anyone tell me how to send GET or POST request with parameters and headers?

Here's my code with parameters. Any idea where should be headers?

```<code>await axios.get('https://www.linkedin.com/oauth/v2/authorization', {
   params: {
      response_type: 'code',
      client_id: 'MY_CODE_HERE',
      redirect_uri: 'http://localhost:8080/auth/login',
      scope: 'r_liteprofile r_emailaddress w_member_social'
   }
}).then(response => {
   console.log("INFO: " + response);
}).catch(error => {
   console.log("ERROR: " + error);
});
``
</code>```

答:
Add a headers part in the config object passed to axios

await axios.get('https://www.linkedin.com/oauth/v2/authorization', {
   response_type: 'code',
   client_id: 'MY_CODE_HERE',
   headers: {
     'X-Header-Name': 'header value',
   },
   redirect_uri: 'http://localhost:8080/auth/login',
   scope: 'r_liteprofile r_emailaddress w_member_social',
}).then(response => {
   console.log("INFO: " + response);
}).catch(error => {
   console.log("ERROR: " + error);
});
```

Body:
All I want is to create LinkedIn login component. I cannot find any information about headers and parameters. Can anyone tell me how to send GET or POST request with parameters and headers?

Here's my code with parameters. Any idea where should be headers?

await axios.get('https://www.linkedin.com/oauth/v2/authorization', {
   params: {
      response_type: 'code',
      client_id: 'MY_CODE_HERE',
      redirect_uri: 'http://localhost:8080/auth/login',
      scope: 'r_liteprofile r_emailaddress w_member_social'
   }
}).then(response => {
   console.log("INFO: " + response);
}).catch(error => {
   console.log("ERROR: " + error);
});
``


问:
Is it a Active Record Class where(), like() limitation?
I got a question on Active Record Class usage, my code snippet below.

```<code>$this->db->select('year, distance, gender, rank, name, chiptime, racenumber');
$this->db->order_by("year", "desc");
$this->db->order_by("distance, gender, rank", "asc");
$year = 2010;
$this->db->where('year', $year);   // where() doesn't work!
$this->db->like('rank', $keyword); // Assume I didn't add like() with $keywords, where() works well.
$this->db->or_like('name', $keyword);
</code>```

When I bind $this->db->like() after $this->db->where() in my Active Recrod Class, the $this->db->where() wont’ work again. It will show all the years record that including the $keyword.

Is it a limitation in Active Recrod Class, or I didn’t find a right way to bind where() and like().

Appreciated for your replies

答:
I think it's the "and" and "or" part. Currently your WHERE looks like this:

WHERE year = 2010 AND rank = 1 OR name = 'Peter'

Since you got an OR there, it will find everything with the name "Peter"  or with rank is 1 and year is 2010.

So you should define your where better and use round brackets where needed.

ContentLicense: CC BY-SA 3.0

Body:
I got a question on Active Record Class usage, my code snippet below.

$this->db->select('year, distance, gender, rank, name, chiptime, racenumber');
$this->db->order_by("year", "desc");
$this->db->order_by("distance, gender, rank", "asc");
$year = 2010;
$this->db->where('year', $year);   // where() doesn't work!
$this->db->like('rank', $keyword); // Assume I didn't add like() with $keywords, where() works well.
$this->db->or_like('name', $keyword);

When I bind $this->db->like() after $this->db->where() in my Active Recrod Class, the $this->db->where() wont’ work again. It will show all the years record that including the $keyword.

Is it a limitation in Active Recrod Class, or I didn’t find a right way to bind where() and like().

Appreciated for your replies


问:
How to Test & Prove my custom Map is thread safe
I was recently asked in an interview to implement a thread safe implementation of Map class in java and assume that no thread safe library exists.

```<code>interface Map{
        void put(String key, String value);
        String get(String key);
        String delete(string key);
 }
</code>```

I wrapped the HashMap and just made the functions synchronized.
Here is my implementation:

```<code>class MyMap{

     Map<String, String> map;

     public MyMap(){
           map = new HashMap<>();
     }

     public synchronized void put(String key, String value){
           map.put(key, value);
     }

     public String get(String key){
           return map.get(key);
     }

    public synchronized String delete(String key){
           return map.remove(key);
     }
</code>```

}

While adding synchronized allows thread safety, I really don't know how to prove if this is correct or not.

I tried writing the following unit test but couldn't really convince that my map is thread safe as I don't know if the get will happen first or put will happen first.

```<code>Thread t1 = new Thread(()->{ map.put("testKey1", "testValue1") });
Thread t2 = new Thread(()->{ map.put("testKey2", "testValue2") });

t1.start();
t2.start();

Thread t3 = new Thread(()->{ System.out.println(map.get("testKey1")) });
Thread t4 = new Thread(()->{ System.out.println(map.get("testKey2")) });

t3.start();
t4.start();

</code>```

I saw the ConcurrentHashMap class' implementation and looks like they use Segments which are too complicated to tell in an interview.

Can someone suggest if my implementation is thread safe, and if yes how to have a test to prove it.

答:
Can someone suggest if my implementation is thread safe ...

Your implementation is NOT thread-safe:

The map variable is not declared as private final.  That means that some other code could reach in and modify or even replace the wrapped Map.  This is (at least!) not thread-safe.  Arguably it is broken irrespective of thread-safety.

The get method accesses the map variable without synchronizing.  That means that there is no happens before relationship between (say) one thread writing to the map (via put or delete) and a second thread reading from it.  The lack of the happens before means that the writes are NOT guaranteed to (always) be visible to the reading thread.  That is a thread-safety bug.

The latter thread-safety bug could manifest as get() requests:

getting stale values, or

not getting a value for a key that should be present, or

getting values for keys that have been deleted, or

unexpected exceptions, or

infinite loops(!).

An application that uses your MyMap class might work on some platforms and not others.   It might fail repeatably, or rarely in ways that are next to impossible to reproduce in a test environment.

.... and if yes how to have a test to prove it.

You cannot prove that code is thread-safe by testing it.  You can only prove something is thread-safe by analyzing the code.  Depending on how rigorous a proof you require, even that can be difficult.

A suitably written test could demonstrate1 that code is NOT thread-safe.  Basically, you need something that shows that the visibility problem (see above) actually manifests as incorrect behavior.  But the catch is that the 2nd flaw involves a behavior that arises from an absence of a guarantee.  The read operation is not guaranteed to see the previous write, but it might see it anyway.  This means that you could run the test on a broken implementation and observe that the test never fails on some platform.  In short, the test not failing doesn't prove anything.

How do you write a test for the above behavior?

Well one thread needs to updates on the MyMap and a second thread needs to perform reads.  And you need to design the test in such a way that the test will fail if the reader sees an incorrect get result.  But designing such a test is difficult because the test itself can trigger (for example) memory cache flushes that obscure the underlying effect you are looking for.  (For example, trace prints can do that.)

1 - Once again this is not a proof.  You have the problem that the testcase itself may be flawed and the supposed evidence of a counter-example to thread safety may therefore be bogus.

Body:
I was recently asked in an interview to implement a thread safe implementation of Map class in java and assume that no thread safe library exists.

interface Map{
        void put(String key, String value);
        String get(String key);
        String delete(string key);
 }

I wrapped the HashMap and just made the functions synchronized.
Here is my implementation:

class MyMap{

     Map<String, String> map;

     public MyMap(){
           map = new HashMap<>();
     }

     public synchronized void put(String key, String value){
           map.put(key, value);
     }

     public String get(String key){
           return map.get(key);
     }

    public synchronized String delete(String key){
           return map.remove(key);
     }

}

While adding synchronized allows thread safety, I really don't know how to prove if this is correct or not.

I tried writing the following unit test but couldn't really convince that my map is thread safe as I don't know if the get will happen first or put will happen first.

Thread t1 = new Thread(()->{ map.put("testKey1", "testValue1") });
Thread t2 = new Thread(()->{ map.put("testKey2", "testValue2") });

t1.start();
t2.start();

Thread t3 = new Thread(()->{ System.out.println(map.get("testKey1")) });
Thread t4 = new Thread(()->{ System.out.println(map.get("testKey2")) });

t3.start();
t4.start();

I saw the ConcurrentHashMap class' implementation and looks like they use Segments which are too complicated to tell in an interview.

Can someone suggest if my implementation is thread safe, and if yes how to have a test to prove it.


问:
How do you compare multiple columns in Excel using Python?
I've got an excel sheet that has values such as:

ProductID
Reference
Component used
DESCRIPTION

5325646
PD-42#23
ASDGE34#W-AL
HOUSING PLATE

4563756
ITA-COPPER
RAW AL
WASHER

4345432
ASDGE34#W-AL
ZK23456
3MM X 2MM X 10MM COPPER BAR

1245456
ASDGE34#W-AL
ZK66634
1MM X 2MM X 9MM COPPER BAR

What I essentially want to do is match anything in "Component" with "Reference" and if they come true, like in this example, ASDGE34#W-AL matches in "Component" and in "Reference", so I'd want to copy the details over and shift it after "Description". The end result that I want to achieve is this.

ProductID
Reference
Component used
DESCRIPTION
Child Component ID
DESCRIPTION

5325646
PD-42#23
ASDGE34#W-AL
HOUSING PLATE
ZK23456 & ZK654534
3MM X 2MM X 10MM COPPER BAR &1MM X 2MM X 9MM COPPER BAR

4563756
ITA-COPPER
ZAAGD0545
ALUMINIUM BAR

5656565
0788866-7#D
YN435611
DUSTER

Can anyone help with this? I've been using Python to try and iterate a loop over the "Components used" and the "Reference" column seeing what match but no luck so far.

答:
I have code that does something similar. I've changed it to suit your problem.

The products are stored in 2 separate dict lists, accessed by Reference and Component used. You can easily iterate over the products_by_reference dict using a Component used value to get a list of products with a matching reference.

Note that this implementation assumes each column header is unique, as each row is stored as a dict where each column header is used as the key to access the corresponding value, so if a header is used twice, the first value will be overwritten. Because of this, I manually rename the header Child DESCRIPTION to DESCRIPTION after writing the header columns.

import os
from collections import defaultdict
import openpyxl

# Load the existing spreadsheet.
wb = openpyxl.load_workbook(filename="Products.xlsx")
ws = wb.worksheets[0]

# Style used for the header row
bold_font = openpyxl.styles.Font(bold=True)
grey_fill = openpyxl.styles.fills.PatternFill("solid", fgColor="F8F9F9")

# Store the header column names and numbers.
# Key = column name, value = column number. e.g. "ProductID": 1
header_columns = {}
for column_num in range(1, ws.max_column + 1):
    column_name = ws.cell(row=1, column=column_num).value
    header_columns[column_name] = column_num

# Read in all the values, starting after the header row.
# Store each product as a dict, and store every product in 2 separate
# dict of lists, with the keys being the reference and component used.
products_by_reference = defaultdict(list)
products_by_component = defaultdict(list)
for row_num in range(2, ws.max_row + 1):
    product = {}
    for column_name, column_num in header_columns.items():
        product[column_name] = ws.cell(row=row_num, column=column_num).value

    reference = product["Reference"]
    component = product["Component used"]
    products_by_reference[reference].append(product)
    products_by_component[component].append(product)

# Iterate over the products by component, and copy and join all the
# components used and descriptions to the relevant product's dict.
for component, products in products_by_component.items():
    # Use dicts here instead of sets if preserving the order is important.
    child_components = set()
    child_descriptions = set()
    for product in products_by_reference[component]:
        child_components.add(product["Component used"])
        child_descriptions.add(product["DESCRIPTION"])

    child_components_string = " & ".join(child_components)
    child_descriptions_string = " & ".join(child_descriptions)
    for product in products:
        product["Child Component ID"] = child_components_string
        product["Child DESCRIPTION"] = child_descriptions_string

    # products_by_reference will be used later for the new spreadsheet, and
    # we don't want to include any products that have a reference which is a
    # component used by another product, since they have now been merged with
    # that other product.
    del products_by_reference[component]

# Write the products to a new spreadsheet.
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "Products"

# Freeze the header row.
ws.freeze_panes = "A2"

# Add the extra headers.
column_num = len(header_columns)
header_columns["Child Component ID"] = column_num + 1
header_columns["Child DESCRIPTION"] = column_num + 2

# Write the headers.
for column_num, column_name in enumerate(header_columns, start=1):
    cell = ws.cell(row=1, column=column_num, value=column_name)
    cell.font = bold_font
    cell.fill = grey_fill

# This implementation doesn't allow there to be duplicate headers, as the
# headers are used as keys to retrieve values from the product dicts. So the
# the last header is manually changed from "Child DESCRIPTION" to
# "DESCRIPTION" after it has been written to the sheet.
cell.value = "DESCRIPTION"

# Flatten the dictionary of lists, and write every product to the spreadsheet.
products = [product for products_list in products_by_reference.values() for product in products_list]
for row_num, product in enumerate(products, start=2):
    for column_name, column_num in header_columns.items():
        cell = ws.cell(row=row_num, column=column_num, value=product.get(column_name))

# Save the spreadsheet to file, then launch it.
filename = "Merged products.xlsx"
wb.save(filename)
os.startfile(filename)
```


问:
FLutter high accuracy with location package
For getting the user's location I am using two packages: location and geocoding. I use location to check if the user has provided location permission or not and to get the LocationData which carries the latitude and longitude.

But as far I have seen location does not provide the property called desiredAccuracy, which
is much needed for my work.

```<code>  static void getCurrentLocation() async {
    Location location = new Location();
    bool _serviceEnabled;
    PermissionStatus _permissionGranted;
    LocationData _locationData;

    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    _locationData = await location.getLocation();
    double latitude = _locationData.latitude!;
    double longitude = _locationData.longitude!;
    List<geocoding.Placemark> placeMark =
        await geocoding.placemarkFromCoordinates(latitude, longitude);
    String country = placeMark.first.country!;
    String isoCountryCode = placeMark.first.isoCountryCode!;
    print("Country: $country and ISO Country Code: $isoCountryCode");

    print(_locationData);
  }
</code>```

My code till now. Is it possible to get something like desiredAccuracy in Location? The only other solution for me would be to use geolocator and permission_handler packages which will require further configurations.

答:
I don't see why you don't want to use geolocator... you've already done the hard work.
Here's how you get the location with desired accuracy

```<code> location = await Geolocator.getCurrentPosition(
  forceAndroidLocationManager: true,
  desiredAccuracy: LocationAccuracy.best
).timeout(Duration(seconds: 20));
</code>```

Here's how to check if service is enabled

```<code>var serviceEnabled = await Geolocator.isLocationServiceEnabled();
</code>```

And here's how to check if permission is granted

```<code>    var permission = await Geolocator.checkPermission();

    if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      // Permissions are denied, next time you could try
      // requesting permissions again (this is also where
      // Android's shouldShowRequestPermissionRationale
      // returned true. According to Android guidelines
      // your App should show an explanatory UI now.
</code>```

Its clearly written in the documentation here
geolocatordoc

Body:
For getting the user's location I am using two packages: location and geocoding. I use location to check if the user has provided location permission or not and to get the LocationData which carries the latitude and longitude.

But as far I have seen location does not provide the property called desiredAccuracy, which
is much needed for my work.

  static void getCurrentLocation() async {
    Location location = new Location();
    bool _serviceEnabled;
    PermissionStatus _permissionGranted;
    LocationData _locationData;

    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    _locationData = await location.getLocation();
    double latitude = _locationData.latitude!;
    double longitude = _locationData.longitude!;
    List<geocoding.Placemark> placeMark =
        await geocoding.placemarkFromCoordinates(latitude, longitude);
    String country = placeMark.first.country!;
    String isoCountryCode = placeMark.first.isoCountryCode!;
    print("Country: $country and ISO Country Code: $isoCountryCode");

    print(_locationData);
  }

My code till now. Is it possible to get something like desiredAccuracy in Location? The only other solution for me would be to use geolocator and permission_handler packages which will require further configurations.

Body:
I don't see why you don't want to use geolocator... you've already done the hard work.
Here's how you get the location with desired accuracy

 location = await Geolocator.getCurrentPosition(
  forceAndroidLocationManager: true,
  desiredAccuracy: LocationAccuracy.best
).timeout(Duration(seconds: 20));

Here's how to check if service is enabled

var serviceEnabled = await Geolocator.isLocationServiceEnabled();

And here's how to check if permission is granted

    var permission = await Geolocator.checkPermission();

    if (permission == LocationPermission.denied) {
    permission = await Geolocator.requestPermission();
    if (permission == LocationPermission.denied) {
      // Permissions are denied, next time you could try
      // requesting permissions again (this is also where
      // Android's shouldShowRequestPermissionRationale
      // returned true. According to Android guidelines
      // your App should show an explanatory UI now.

Its clearly written in the documentation here
geolocatordoc


问:
How to validate GitHub webhook with Deno?
I'm trying to make a GitHub webhook server with Deno, but I cannot find any possible way to do the validation.

This is my current attempt using webhooks-methods.js:

```<code>import { Application } from "https://deno.land/x/oak/mod.ts";
import { verify } from "https://cdn.skypack.dev/@octokit/webhooks-methods?dts";

const app = new Application();

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (_err) {
    ctx.response.status = 500;
  }
});

const secret = "...";

app.use(async (ctx) => {
  const signature = ctx.request.headers.get("X-Hub-Signature-256");
  if (signature) {
    const payload = await ctx.request.body({ type: "text" }).value;
    const result = await verify(secret, payload, signature);
    console.log(result);
  }
  ctx.response.status = 200;
});
</code>```

The verify function is returning false every time.

答:
Your example is very close. The GitHub webhook documentation details the signature header schema. The value is a digest algorithm prefix followed by the signature, in the format of ${ALGO}=${SIGNATURE}:

```<code>X-Hub-Signature-256: sha256=d57c68ca6f92289e6987922ff26938930f6e66a2d161ef06abdf1859230aa23c
</code>```

So, you need to extract the signature from the value (omitting the prefix):

const signatureHeader = request.headers.get("X-Hub-Signature-256");
const signature = signatureHeader.slice("sha256=".length);
```
<blockquote>
<p><strong>Update</strong>: Starting in release version <code>3.0.1</code> of <code>octokit/webhooks-methods.js</code>, it is no longer necessary to manually extract the signature from the header — that task is handled by the <code>verify</code> function. The code in the answer has been updated to reflect this change.</p>
</blockquote>
<hr />
<p>Here's a complete, working example that you can simply copy + paste into a project or playground on Deno Deploy:</p>
<p><code>gh-webhook-logger.ts</code>:</p>
<pre class="lang-ts prettyprint-override"><code>import { assert } from "https://deno.land/std@0.177.0/testing/asserts.ts";

import {
  Application,
  NativeRequest,
  Router,
} from "https://deno.land/x/oak@v11.1.0/mod.ts";

import type { ServerRequest } from "https://deno.land/x/oak@v11.1.0/types.d.ts";

import { verify } from "https://esm.sh/@octokit/webhooks-methods@3.0.2?pin=v106";

// In actual usage, use a private secret:
// const SECRET = Deno.env.get("SIGNING_SECRET");

// But for the purposes of this demo, the exposed secret is:
const SECRET = "Let me know if you found this to be helpful!";

type GitHubWebhookVerificationStatus = {
  id: string;
  verified: boolean;
};

// Because this uses a native Request,
// it can be used in other contexts besides Oak (e.g. `std/http/serve`):
async function verifyGitHubWebhook(
  request: Request,
): Promise<GitHubWebhookVerificationStatus> {
  const id = request.headers.get("X-GitHub-Delivery");

  // This should be more strict in reality
  assert(id, "Not a GH webhhok");

  const signatureHeader = request.headers.get("X-Hub-Signature-256");
  let verified = false;

  if (signatureHeader) {
    const payload = await request.clone().text();
    verified = await verify(SECRET, payload, signatureHeader);
  }

  return { id, verified };
}

// Type predicate used to access native Request instance
// Ref: https://github.com/oakserver/oak/issues/501#issuecomment-1084046581
function isNativeRequest(r: ServerRequest): r is NativeRequest {
  // deno-lint-ignore no-explicit-any
  return (r as any).request instanceof Request;
}

const webhookLogger = new Router().post("/webhook", async (ctx) => {
  assert(isNativeRequest(ctx.request.originalRequest));
  const status = await verifyGitHubWebhook(ctx.request.originalRequest.request);
  console.log(status);
  ctx.response.status = 200;
});

const app = new Application()
  .use(webhookLogger.routes())
  .use(webhookLogger.allowedMethods());

// The port is not important in Deno Deploy
await app.listen({ port: 8080 });

</code>```

Body:
I'm trying to make a GitHub webhook server with Deno, but I cannot find any possible way to do the validation.

This is my current attempt using webhooks-methods.js:

import { Application } from "https://deno.land/x/oak/mod.ts";
import { verify } from "https://cdn.skypack.dev/@octokit/webhooks-methods?dts";

const app = new Application();

app.use(async (ctx, next) => {
  try {
    await next();
  } catch (_err) {
    ctx.response.status = 500;
  }
});

const secret = "...";

app.use(async (ctx) => {
  const signature = ctx.request.headers.get("X-Hub-Signature-256");
  if (signature) {
    const payload = await ctx.request.body({ type: "text" }).value;
    const result = await verify(secret, payload, signature);
    console.log(result);
  }
  ctx.response.status = 200;
});

The verify function is returning false every time.

Body:
Your example is very close. The GitHub webhook documentation details the signature header schema. The value is a digest algorithm prefix followed by the signature, in the format of ${ALGO}=${SIGNATURE}:

X-Hub-Signature-256: sha256=d57c68ca6f92289e6987922ff26938930f6e66a2d161ef06abdf1859230aa23c

So, you need to extract the signature from the value (omitting the prefix):

const signatureHeader = request.headers.get("X-Hub-Signature-256");
const signature = signatureHeader.slice("sha256=".length);

Update: Starting in release version 3.0.1 of octokit/webhooks-methods.js, it is no longer necessary to manually extract the signature from the header — that task is handled by the verify function. The code in the answer has been updated to reflect this change.

Here's a complete, working example that you can simply copy + paste into a project or playground on Deno Deploy:

gh-webhook-logger.ts:

import { assert } from "https://deno.land/std@0.177.0/testing/asserts.ts";

import {
  Application,
  NativeRequest,
  Router,
} from "https://deno.land/x/oak@v11.1.0/mod.ts";

import type { ServerRequest } from "https://deno.land/x/oak@v11.1.0/types.d.ts";

import { verify } from "https://esm.sh/@octokit/webhooks-methods@3.0.2?pin=v106";

// In actual usage, use a private secret:
// const SECRET = Deno.env.get("SIGNING_SECRET");

// But for the purposes of this demo, the exposed secret is:
const SECRET = "Let me know if you found this to be helpful!";

type GitHubWebhookVerificationStatus = {
  id: string;
  verified: boolean;
};

// Because this uses a native Request,
// it can be used in other contexts besides Oak (e.g. `std/http/serve`):
async function verifyGitHubWebhook(
  request: Request,
): Promise<GitHubWebhookVerificationStatus> {
  const id = request.headers.get("X-GitHub-Delivery");

  // This should be more strict in reality
  assert(id, "Not a GH webhhok");

  const signatureHeader = request.headers.get("X-Hub-Signature-256");
  let verified = false;

  if (signatureHeader) {
    const payload = await request.clone().text();
    verified = await verify(SECRET, payload, signatureHeader);
  }

  return { id, verified };
}

// Type predicate used to access native Request instance
// Ref: https://github.com/oakserver/oak/issues/501#issuecomment-1084046581
function isNativeRequest(r: ServerRequest): r is NativeRequest {
  // deno-lint-ignore no-explicit-any
  return (r as any).request instanceof Request;
}

const webhookLogger = new Router().post("/webhook", async (ctx) => {
  assert(isNativeRequest(ctx.request.originalRequest));
  const status = await verifyGitHubWebhook(ctx.request.originalRequest.request);
  console.log(status);
  ctx.response.status = 200;
});

const app = new Application()
  .use(webhookLogger.routes())
  .use(webhookLogger.allowedMethods());

// The port is not important in Deno Deploy
await app.listen({ port: 8080 });


问:
Add rows to Google Sheets sheet if not enough
I have a bunch of data that I routinely use a Python script to back up into a Google Sheets sheet. It's currently at 5385 rows filled with 6041 total. I know that if I try to upload more than 6041 rows the update will fail, but I know that I can fix this by opening up the sheet, scrolling all the way to the bottom, and then clicking "All 1000 more rows at bottom" a few times.

Is there a way for googleapiclient to automatically make sure that there's room in the sheet?

Edit:

```<code>        cells = 'Backup!A{}:{}{}'.format(start_ind, self._excel_column_index(len(headers)), start_ind + len(to_cache) + 1)

        values = self._excel_serialize_arb_array(to_cache, headers)
        data = {'values':values}
        self.sheet.values().update(spreadsheetId=self.spreadsheet_ids['FOO'],
                        range=cells, valueInputOption='USER_ENTERED',
                        body=data).execute()
</code>```

答:
You would need to update the properties of the Sheet itself or create a sheet with the properties of more than 1000 rows.

Note: I build the code over apps script before your edit with your code.

/**
 * Add a new sheet with some properties.
 * @param {string} yourspreadsheetId The spreadsheet ID.
 */
// This funcion would add a sheet with 10,000 rows that would be empty and that they can be filled

function addSheet() {
   const spreadsheetId = "yourspreeadsheetID";

  var requests = [{
    'addSheet': {
      'properties': {
        'title': 'Deposits',
        'gridProperties': {
          'rowCount': 100000,
          'columnCount': 2
        },
        'tabColor': {
          'red': 1.0,
          'green': 0.3,
          'blue': 0.4
        }
      }
    }
  }];

  var response =
      Sheets.Spreadsheets.batchUpdate({'requests': requests}, spreadsheetId);
  Logger.log('Created sheet with ID: ' +
      response.replies[0].addSheet.properties.sheetId);
}

// This function is to write all 10,000 rows bypassing the 1000 limit that you might be having

function myFunction() {
  const spreadsheetId = "yourspreadsheetID";
  //  Spreadsheet ID.
  const max = 10000;
  const data = [];

  for (let i = 0; i < max; i++) {
    data.push({range: `Deposits!A${i + 1}`, values: [[`A${i + 1}`]]});
  }
  Sheets.Spreadsheets.Values.batchUpdate({data: data, valueInputOption: "USER_ENTERED"}, spreadsheetId);
}```

I run the first function to create the Sheet with the properties using the "batchUpdate" and was able to add 10,000 strings to it.

I would assume that on Python you need to increase the number of rows in the sheet using an UpdateSheetPropertiesRequest or InsertDimensionRequest check it here: Sheet API update properties!

Body:
I have a bunch of data that I routinely use a Python script to back up into a Google Sheets sheet. It's currently at 5385 rows filled with 6041 total. I know that if I try to upload more than 6041 rows the update will fail, but I know that I can fix this by opening up the sheet, scrolling all the way to the bottom, and then clicking "All 1000 more rows at bottom" a few times.

Is there a way for googleapiclient to automatically make sure that there's room in the sheet?

Edit:

        cells = 'Backup!A{}:{}{}'.format(start_ind, self._excel_column_index(len(headers)), start_ind + len(to_cache) + 1)

        values = self._excel_serialize_arb_array(to_cache, headers)
        data = {'values':values}
        self.sheet.values().update(spreadsheetId=self.spreadsheet_ids['FOO'],
                        range=cells, valueInputOption='USER_ENTERED',
                        body=data).execute()

Body:
You would need to update the properties of the Sheet itself or create a sheet with the properties of more than 1000 rows.

Note: I build the code over apps script before your edit with your code.

/**
 * Add a new sheet with some properties.
 * @param {string} yourspreadsheetId The spreadsheet ID.
 */
// This funcion would add a sheet with 10,000 rows that would be empty and that they can be filled

function addSheet() {
   const spreadsheetId = "yourspreeadsheetID";

  var requests = [{
    'addSheet': {
      'properties': {
        'title': 'Deposits',
        'gridProperties': {
          'rowCount': 100000,
          'columnCount': 2
        },
        'tabColor': {
          'red': 1.0,
          'green': 0.3,
          'blue': 0.4
        }
      }
    }
  }];

  var response =
      Sheets.Spreadsheets.batchUpdate({'requests': requests}, spreadsheetId);
  Logger.log('Created sheet with ID: ' +
      response.replies[0].addSheet.properties.sheetId);
}

// This function is to write all 10,000 rows bypassing the 1000 limit that you might be having

function myFunction() {
  const spreadsheetId = "yourspreadsheetID";
  //  Spreadsheet ID.
  const max = 10000;
  const data = [];

  for (let i = 0; i < max; i++) {
    data.push({range: `Deposits!A${i + 1}`, values: [[`A${i + 1}`]]});
  }
  Sheets.Spreadsheets.Values.batchUpdate({data: data, valueInputOption: "USER_ENTERED"}, spreadsheetId);
}

I run the first function to create the Sheet with the properties using the "batchUpdate" and was able to add 10,000 strings to it.

I would assume that on Python you need to increase the number of rows in the sheet using an UpdateSheetPropertiesRequest or InsertDimensionRequest check it here: Sheet API update properties!


问:
R plotly line chart
I have a data set with three variables namely Gender, Age and BMI and this is the sample of data:

I am trying to plot line chart in r using plotly package, where X axis shows BMI values, Y axis shows Age and Gender plot two lines as a values corresponding to BMI and Age. I am trying these code but could not got proper output.

Here is my code:

```<code>    library(plotly)
data<-read.csv("abc1.csv")
p <- plot_ly(data, x = ~BMI, y = ~Age, type = 'scatter', mode = 'lines',
             linetype = ~Gender,line = list(color = 'rgb(205, 12, 24)', width = 4)) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))
p
</code>```

Here is my console output:

答:
Recreating data frame:

First, I tried to recreate your data below:

```<code>Gender <- c("M",
            "F",
            "F",
            "M",
            "M",
            "F",
            "M",
            "M",
            "M",
            "F",
            "F",
            "M",
            "M")
Age <- c(75.6,
         81.9,
         81.9,
         83.2,
         84.6,
         84.9,
         88,
         89.1,
         90.1,
         90.4,
         92.9,
         93,
         93.4)
BMI <- c(16.2,
         17.3,
         14.9,
         19.6,
         15.5,
         14.7,
         15,
         14.8,
         19.2,
         16.4,
         16.1,
         15.7,
         25.2)
df <- data.frame(Gender,
                 Age,
                 BMI)
df
</code>```

Which gives us this:

```<code>   Gender  Age  BMI
1       M 75.6 16.2
2       F 81.9 17.3
3       F 81.9 14.9
4       M 83.2 19.6
5       M 84.6 15.5
6       F 84.9 14.7
7       M 88.0 15.0
8       M 89.1 14.8
9       M 90.1 19.2
10      F 90.4 16.4
11      F 92.9 16.1
12      M 93.0 15.7
13      M 93.4 25.2
</code>```

Creating the plot (plotly method)

What is probably wrong here is the way you have faceted your data. I have edited your code like this:

```<code>library(plotly)
p <- plot_ly(df,
             x = ~Age,
             y = ~BMI,
             type = 'scatter',
             mode = 'lines',
             color = ~Gender) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))
p
</code>```

Which facets the data correctly here:

If you are dead set on adding line types per gender, you can also just do the same thing for line type:

```<code>p <- plot_ly(df,
             x = ~Age,
             y = ~BMI,
             type = 'scatter',
             mode = 'lines',
             color = ~Gender,
             linetype = ~Gender) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))
</code>```

Which makes this:

Creating the plot (ggpubr method)

One way you could do it is by porting a ggpubr or ggplot line graph into the ggplotly function which serves the same function. I used my own palette for the colors, but you can select whatever color you want with RGB codes:

```<code>library(ggpubr)
line <- ggline(df,
       x="Age",
       y="BMI",
       color = "Gender",
       palette = c("#00AFBB", "#E7B800"),
       title = "Line Graph")
ggplotly(line)
</code>```

Which makes this plotly line graph:

Again, not sure from your code what you were trying to do, but you can also make a red and dashed type line with this method:

```<code>line <- ggline(df,
       x="Age",
       y="BMI",
       linetype = "Gender",
       color = "red",
       title = "Line Graph")
ggplotly(line)
</code>```

Which makes this:

Title: R plotly line chart

Body:
I have a data set with three variables namely Gender, Age and BMI and this is the sample of data:

I am trying to plot line chart in r using plotly package, where X axis shows BMI values, Y axis shows Age and Gender plot two lines as a values corresponding to BMI and Age. I am trying these code but could not got proper output.

Here is my code:

    library(plotly)
data<-read.csv("abc1.csv")
p <- plot_ly(data, x = ~BMI, y = ~Age, type = 'scatter', mode = 'lines',
             linetype = ~Gender,line = list(color = 'rgb(205, 12, 24)', width = 4)) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))
p

Here is my console output:

Body:
Recreating data frame:

First, I tried to recreate your data below:

Gender <- c("M",
            "F",
            "F",
            "M",
            "M",
            "F",
            "M",
            "M",
            "M",
            "F",
            "F",
            "M",
            "M")
Age <- c(75.6,
         81.9,
         81.9,
         83.2,
         84.6,
         84.9,
         88,
         89.1,
         90.1,
         90.4,
         92.9,
         93,
         93.4)
BMI <- c(16.2,
         17.3,
         14.9,
         19.6,
         15.5,
         14.7,
         15,
         14.8,
         19.2,
         16.4,
         16.1,
         15.7,
         25.2)
df <- data.frame(Gender,
                 Age,
                 BMI)
df

Which gives us this:

   Gender  Age  BMI
1       M 75.6 16.2
2       F 81.9 17.3
3       F 81.9 14.9
4       M 83.2 19.6
5       M 84.6 15.5
6       F 84.9 14.7
7       M 88.0 15.0
8       M 89.1 14.8
9       M 90.1 19.2
10      F 90.4 16.4
11      F 92.9 16.1
12      M 93.0 15.7
13      M 93.4 25.2

Creating the plot (plotly method)

What is probably wrong here is the way you have faceted your data. I have edited your code like this:

library(plotly)
p <- plot_ly(df,
             x = ~Age,
             y = ~BMI,
             type = 'scatter',
             mode = 'lines',
             color = ~Gender) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))
p

Which facets the data correctly here:

If you are dead set on adding line types per gender, you can also just do the same thing for line type:

p <- plot_ly(df,
             x = ~Age,
             y = ~BMI,
             type = 'scatter',
             mode = 'lines',
             color = ~Gender,
             linetype = ~Gender) %>%
  layout(title = "Line chart",
         xaxis = list(title = "Age"),
         yaxis = list (title = "BMI"))

Which makes this:

Creating the plot (ggpubr method)

One way you could do it is by porting a ggpubr or ggplot line graph into the ggplotly function which serves the same function. I used my own palette for the colors, but you can select whatever color you want with RGB codes:

library(ggpubr)
line <- ggline(df,
       x="Age",
       y="BMI",
       color = "Gender",
       palette = c("#00AFBB", "#E7B800"),
       title = "Line Graph")
ggplotly(line)

Which makes this plotly line graph:

Again, not sure from your code what you were trying to do, but you can also make a red and dashed type line with this method:

line <- ggline(df,
       x="Age",
       y="BMI",
       linetype = "Gender",
       color = "red",
       title = "Line Graph")
ggplotly(line)

Which makes this:


问:
Connecting with EWS API service to outlook.com account with oAuth2 token
I'm able to authenticate with live.com with my account on outlook.com at url

```<code>https://login.microsoftonline.com/common/v2.0
</code>```

I receive an accessToken and id token.

My question is whether I can use this accessToken to retrieve exchange data about my emails through EWS API service using this token? ExchangeService.

```<code>   _exchangeService = new ExchangeService(ExchangeVersion.Exchange2007_SP1) { ConnectionGroupName = Guid.NewGuid().ToString() };
                    _exchangeService.Credentials = new WebCredentials("xxxxxxx", "xxxxxxxx", "outlook.com");
                 //  _credentials = new OAuthCredentials(user.PasswordToken);
                    // Set the URL.
                    _exchangeService.TraceEnabled = true;
                    _exchangeService.AutodiscoverUrl("xxxxx")
</code>```

Authenticate to Outlook 365 through the ExchangeService.asmx in the following URL for exchange service as done in the following sample.

```<code>> https://outlook.office365.com/EWS/Exchange.asmx
</code>```

My question is whether I can retrieve email data from exchange service ASMX with the idToken/accessToken supplied from live.com for outlook.com accounts?

答:
I believe EWS still works for Outlook.com accounts with BASIC(username,password) auth. We used to use it before migrating to Graph API. You'd need to ask your Outlook users to generate a special App Password though.

To simplify your Exchange/Outlook integrations check out Aurinko API

Body:
I'm able to authenticate with live.com with my account on outlook.com at url

https://login.microsoftonline.com/common/v2.0

I receive an accessToken and id token.

My question is whether I can use this accessToken to retrieve exchange data about my emails through EWS API service using this token? ExchangeService.

   _exchangeService = new ExchangeService(ExchangeVersion.Exchange2007_SP1) { ConnectionGroupName = Guid.NewGuid().ToString() };
                    _exchangeService.Credentials = new WebCredentials("xxxxxxx", "xxxxxxxx", "outlook.com");
                 //  _credentials = new OAuthCredentials(user.PasswordToken);
                    // Set the URL.
                    _exchangeService.TraceEnabled = true;
                    _exchangeService.AutodiscoverUrl("xxxxx")

Authenticate to Outlook 365 through the ExchangeService.asmx in the following URL for exchange service as done in the following sample.

> https://outlook.office365.com/EWS/Exchange.asmx

My question is whether I can retrieve email data from exchange service ASMX with the idToken/accessToken supplied from live.com for outlook.com accounts?


问:
Flutter Windows Desktop Support
Im currently working on a MacBook developing a Flutter app for Android and IOS, and both are running fine on simulators from my Mac. I use VS Code.

Now I want to add desktop support to it (specifically Windows) but I just read that in order to do that, it has to be built on Windows.

Does that mean I’ll have to create a new project on a Windows PC and manually copy all of my files to it and have 2 different set of codes?

答:
You need a Windows environment to enable windows support.

```<code>on Windows, you can dev: android + web + windows
on macOS, you can dev: android + web + iOS + macOS
on Linux, you can dev: anroid + web + linux
</code>```

You can share the same project among these environments. Once you enable a certain platform, it will create a separate folder for it. So if you enable multiple, your project will simply have multiple folders in its root, such as "ios", "web", "macos", etc.

For windows, you also need to install VS2022, for macOS you need XCODE, for Linux you also need some tools (the installation is made into a script, so just run that).

For more info, head over to flutter.dev.

Title: Flutter Windows Desktop Support

Body:
You need a Windows environment to enable windows support.

on Windows, you can dev: android + web + windows
on macOS, you can dev: android + web + iOS + macOS
on Linux, you can dev: anroid + web + linux

You can share the same project among these environments. Once you enable a certain platform, it will create a separate folder for it. So if you enable multiple, your project will simply have multiple folders in its root, such as "ios", "web", "macos", etc.

For windows, you also need to install VS2022, for macOS you need XCODE, for Linux you also need some tools (the installation is made into a script, so just run that).

For more info, head over to flutter.dev.