问:
Can we use reflection to instantiate custom TypeScript model from a JSON string?
Is it possible to clone a JSON-generated object or string into a Typescript class which I created?  We are building a model of our API using Typescript classes.  There’s a base class which they all extend which has common/helper methods.  When we do JSON.parse(response) to auto-generate objects it creates simple objects and not our custom objects.

Is there a way we can convert those JSON-generated objects into our custom objects, so long as the field names match up?  And, to make things more robust, can this but done where our custom objects’ fields are other custom objects and/or arrays of them?

Here is our code, with comments of what we’d like to achieve.

base-model.ts

```<code>export class BaseModelObject {
    uuid: string; // All of our objects in our model and JSON have this required field populated
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }
}
</code>```

child-model.ts

```<code>import { BaseModelObject } from 'base-model';
export class Child extends BaseModelObject {
}
</code>```

parent-model.ts

```<code>import { BaseModelObject } from 'base-model';
import { Child } from 'child-model';
export class Parent extends BaseModelObject {
  children: Child[];
}
</code>```

JSON payload

```<code>{
    'uuid': '0632a35c-e7dd-40a8-b5f4-f571a8359c1a',
    'children': [
        {
            'uuid': 'd738c408-4ae9-430d-a64d-ba3f085175fc'
        },
        {
            'uuid': '44d56a0d-ad2d-4e85-b5d1-da4371fc0e5f'
        }
    ]
}
</code>```

In our components and directives and such, we hope to use the helper function in BaseModelObject:

Component code

```<code>let parent: Parent = JSON.parse(response);
console.log(parent.uuid); // Works!  0632a35c-e7dd-40a8-b5f4-f571a8359c1a

// Want this to print ‘true’, but instead we get TypeError: parebt.matchUUID is not a function
console.log(parent.matchUUID(‘0632a35c-e7dd-40a8-b5f4-f571a8359c1a’));

// Want this to print ‘true’, but instead we get TypeError: parent.children[0].matchUUID is not a function
console.log(parent.children[0].matchUUID(‘d738c408-4ae9-430d-a64d-ba3f085175fc’));
</code>```

The problem is that JSON.parse() is not creating our classes, it’s creating simple objects with key/value pairs.  So we’re thinking of “cloning” the JSON-generated object into an instance of our class, like this:

base-model.ts

```<code>export class BaseModelObject {

    [key: string]: any;

    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj['uuid'] == this['uuid'];
    }

    cloneFields(obj: any) {
        for (let prop in obj) {
            this[prop] = obj[prop];
        }
    }
}
</code>```

Component code

```<code>let parent: Parent = new Parent(); // Creates instance of our class
parent.cloneFields(JSON.parse(response)); // Copy JSON fields to our object
console.log(parent.matchUUID('0632a35c-e7dd-40a8-b5f4-f571a8359c1a')); // prints 'true'
console.log(parent.children[0].matchUUID('d738c408-4ae9-430d-a64d-ba3f085175fc')); // Still throws TypeError: parent.children[0].matchUUID is not a function
</code>```

The problem now rests in the fact that the cloning of the Parent object did not recursively clone the JSON-generated Child objects into instances of our custom Child class.

Since our Parent object is typed at compile-time and it knows that the data type of the children array is Child[] (our custom class), is there a way to use reflection to instantiate the right class?

Our logic would need to say:

Create an instance of our custom class

Tell our instance to clone the fields from the JSON-generated object

Iterate over the fields in the JSON-generated object

For each field name from the JSON-generated object, find the "type definition" in our custom class

If the type definition is not a primitive or native Typescript type, then instantiate a new instance of that "type" and then clone it's fields.

(and it would need to recursively traverse the whole JSON object structure to match up all other custom classes/objects we add to our model).

So something like:

```<code>cloneFields(obj: any) {
    for (let prop in obj) {
        let A: any = ...find the data type of prop...
        if(...A is a primitive type ...) {
            this[prop] = obj[prop];
        } else {
          // Yes, I know this code won't compile.
          // Just trying to illustrate how to instantiate
          let B: <T extends BaseModelUtil> = ...instantiate an instance of A...
          B.cloneFields(prop);
          A[prop] = B;
        }
    }
}
</code>```

Is it possible to reflect a data type from a class variable definition and then instantiate it at runtime?

Or if I'm going down an ugly rabbit hole to which you know a different solution, I'd love to hear it.  We simply want to build our custom objects from a JSON payload without needing to hand-code the same patterns over and over since we expect our model to grow into dozens of objects and hundreds of fields.

Thanks in advance!
Michael

答:
There are several ways to do that, but some requires more work and maintenance than others.

1. Simple, a lot of work

Make your cloneFields abstract and implement it in each class.

export abstract class BaseModelObject {
    uuid: string;
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }

    abstract cloneFields(obj: any);
}

class Parent extends BaseModelObject {
    children: Child[];

    cloneFields(obj: any) {
        this.children = obj.children?.map(child => {
            const c = new Children();
            c.cloneFields(child);
            return c;
        });
    }
}
```
<p><strong>2. Simple, hacky way</strong></p>
<p><em>If there is no polymorphism like:</em></p>
<pre class="lang-js prettyprint-override"><code>class Parent extends BaseModelObject {
    children: Child[] = [ new Child(), new ChildOfChild(), new SomeOtherChild() ]
}
</code>```

Property names mapped to types.

const Map = {
    children: Child,
    parent: Parent,
    default: BaseModelObject
}

export class BaseModelObject {
    uuid: string;
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }

    cloneFields(obj: any) {
        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                this[prop] = obj[prop]?.map(child => { // You have to check it is an array or not,..
                    const c = new (Map[prop])();
                    c.cloneFields(child);
                    return c;
                });
            }
        }
    }
}
```
<p>You can serialize hints into that JSON. Eg. property <code>type</code> with source/target type name and use it to resolve right types.</p>
<p><strong>3. Reflection</strong></p>
<p>Try tst-reflect. It is pretty advanced Reflection system for TypeScript (<em>using custom typescript transformer plugin</em>).</p>
<p>I'm not going to write example, it would be too complex and it depends on your needs.</p>
<p>You can use <code>tst-reflect</code> to list type's properties and get their types. So you'll be able to validace parsed data too.</p>
<p>Just some showcase from its README:</p>
<pre class="lang-js prettyprint-override"><code>import { getType } from "tst-reflect";

function printTypeProperties<TType>()
{
    const type = getType<TType>(); // <<== get type of generic TType ;)

    console.log(type.getProperties().map(prop => prop.name + ": " + prop.type.name).join("\n"));
}

interface SomeType {
    foo: string;
    bar: number;
    baz: Date;
}

printTypeProperties<SomeType>();

// or direct
getType<SomeType>().getProperties();
</code>```

EDIT:

I created a package ng-custom-transformers that simplifies this a lot. Follow its README.

DEMO

EDIT old:

Usage with Angular

Angular has no direct support of custom transformers/plugins. There is a feature request in the Angular Github repo.

But there is a workaround.

You have to add ngx-build-plus. Run ng add ngx-build-plus.
That package defines "plugins".

Plugins allow you to provide some custom code that modifies your webpack configuration.

So you can create plugin and extend Angular's webpack configuration. But here comes the <s>sun</s> problem. There is no public way to add the transformer. There were AngularCompilerPlugin in webpack configuration (@ngtools/webpack) which had private _transformers property. It was possible to add a transformer into that array property. But AngularCompilerPlugin has been replaced by AngularWebpackPlugin which has no such property. But is is possible to override method of AngularWebpackPlugin and add a transformer there. Getting an instance of the AngularWebpackPlugin is possible thanks to ngx-build-plus's plugins.

Code of the plugin

const {AngularWebpackPlugin} = require("@ngtools/webpack");
const tstReflectTransform = require("tst-reflect-transformer").default;

module.exports.default = {
  pre() {},
  post() {},

  config(cfg) {
    // Find the AngularWebpackPlugin in the webpack configuration; angular > 12
    const angularWebpackPlugin = cfg.plugins.find((plugin) => plugin instanceof AngularWebpackPlugin);

    if (!angularWebpackPlugin) {
      console.error("Could not inject the typescript transformer: AngularWebpackPlugin not found");
      return;
    }

    addTransformerToAngularWebpackPlugin(angularWebpackPlugin, transformer);

    return cfg;
  },
};

function transformer(builderProgram) {
  return tstReflectTransform(builderProgram.getProgram());
}

function addTransformerToAngularWebpackPlugin(plugin, transformer) {
  const originalCreateFileEmitter = plugin.createFileEmitter; // private method

  plugin.createFileEmitter = function (programBuilder, transformers, getExtraDependencies, onAfterEmit, ...rest) {
    if (!transformers) {
      transformers = {};
    }

    if (!transformers.before) {
      transformers = {before: []};
    }

    transformers.before = [transformer(programBuilder), ...transformers.before];

    return originalCreateFileEmitter.apply(plugin, [programBuilder, transformers, getExtraDependencies, onAfterEmit, ...rest]);
  };
}
```

Then it is required to execute ng commands (such as serve or build) with --plugin path/to/the/plugin.js.

I've made working StackBlitz demo.

Resources I've used while preparing the Angular demo:

https://indepth.dev/posts/1045/having-fun-with-angular-and-typescript-transformers

https://medium.com/@morrys/custom-typescript-transformers-with-angular-for-angular-11-12-and-13-40cbdc9cca7b

Body:
Is it possible to clone a JSON-generated object or string into a Typescript class which I created?  We are building a model of our API using Typescript classes.  There’s a base class which they all extend which has common/helper methods.  When we do JSON.parse(response) to auto-generate objects it creates simple objects and not our custom objects.

Is there a way we can convert those JSON-generated objects into our custom objects, so long as the field names match up?  And, to make things more robust, can this but done where our custom objects’ fields are other custom objects and/or arrays of them?

Here is our code, with comments of what we’d like to achieve.

base-model.ts

export class BaseModelObject {
    uuid: string; // All of our objects in our model and JSON have this required field populated
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }
}

child-model.ts

import { BaseModelObject } from 'base-model';
export class Child extends BaseModelObject {
}

parent-model.ts

import { BaseModelObject } from 'base-model';
import { Child } from 'child-model';
export class Parent extends BaseModelObject {
  children: Child[];
}

JSON payload

{
    'uuid': '0632a35c-e7dd-40a8-b5f4-f571a8359c1a',
    'children': [
        {
            'uuid': 'd738c408-4ae9-430d-a64d-ba3f085175fc'
        },
        {
            'uuid': '44d56a0d-ad2d-4e85-b5d1-da4371fc0e5f'
        }
    ]
}

In our components and directives and such, we hope to use the helper function in BaseModelObject:

Component code

let parent: Parent = JSON.parse(response);
console.log(parent.uuid); // Works!  0632a35c-e7dd-40a8-b5f4-f571a8359c1a

// Want this to print ‘true’, but instead we get TypeError: parebt.matchUUID is not a function
console.log(parent.matchUUID(‘0632a35c-e7dd-40a8-b5f4-f571a8359c1a’));

// Want this to print ‘true’, but instead we get TypeError: parent.children[0].matchUUID is not a function
console.log(parent.children[0].matchUUID(‘d738c408-4ae9-430d-a64d-ba3f085175fc’));

The problem is that JSON.parse() is not creating our classes, it’s creating simple objects with key/value pairs.  So we’re thinking of “cloning” the JSON-generated object into an instance of our class, like this:

base-model.ts

export class BaseModelObject {

    [key: string]: any;

    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj['uuid'] == this['uuid'];
    }

    cloneFields(obj: any) {
        for (let prop in obj) {
            this[prop] = obj[prop];
        }
    }
}

Component code

let parent: Parent = new Parent(); // Creates instance of our class
parent.cloneFields(JSON.parse(response)); // Copy JSON fields to our object
console.log(parent.matchUUID('0632a35c-e7dd-40a8-b5f4-f571a8359c1a')); // prints 'true'
console.log(parent.children[0].matchUUID('d738c408-4ae9-430d-a64d-ba3f085175fc')); // Still throws TypeError: parent.children[0].matchUUID is not a function

The problem now rests in the fact that the cloning of the Parent object did not recursively clone the JSON-generated Child objects into instances of our custom Child class.

Since our Parent object is typed at compile-time and it knows that the data type of the children array is Child[] (our custom class), is there a way to use reflection to instantiate the right class?

Our logic would need to say:

Create an instance of our custom class

Tell our instance to clone the fields from the JSON-generated object

Iterate over the fields in the JSON-generated object

For each field name from the JSON-generated object, find the "type definition" in our custom class

If the type definition is not a primitive or native Typescript type, then instantiate a new instance of that "type" and then clone it's fields.

(and it would need to recursively traverse the whole JSON object structure to match up all other custom classes/objects we add to our model).

So something like:

cloneFields(obj: any) {
    for (let prop in obj) {
        let A: any = ...find the data type of prop...
        if(...A is a primitive type ...) {
            this[prop] = obj[prop];
        } else {
          // Yes, I know this code won't compile.
          // Just trying to illustrate how to instantiate
          let B: <T extends BaseModelUtil> = ...instantiate an instance of A...
          B.cloneFields(prop);
          A[prop] = B;
        }
    }
}

Is it possible to reflect a data type from a class variable definition and then instantiate it at runtime?

Or if I'm going down an ugly rabbit hole to which you know a different solution, I'd love to hear it.  We simply want to build our custom objects from a JSON payload without needing to hand-code the same patterns over and over since we expect our model to grow into dozens of objects and hundreds of fields.

Thanks in advance!
Michael

Body:
There are several ways to do that, but some requires more work and maintenance than others.

1. Simple, a lot of work

Make your cloneFields abstract and implement it in each class.

export abstract class BaseModelObject {
    uuid: string;
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }

    abstract cloneFields(obj: any);
}

class Parent extends BaseModelObject {
    children: Child[];

    cloneFields(obj: any) {
        this.children = obj.children?.map(child => {
            const c = new Children();
            c.cloneFields(child);
            return c;
        });
    }
}

2. Simple, hacky way

If there is no polymorphism like:

class Parent extends BaseModelObject {
    children: Child[] = [ new Child(), new ChildOfChild(), new SomeOtherChild() ]
}

Property names mapped to types.

const Map = {
    children: Child,
    parent: Parent,
    default: BaseModelObject
}

export class BaseModelObject {
    uuid: string;
    matchUUIDs<T extends BaseModelObject>( obj: T): boolean {
        return obj.uuid == this.uuid;
    }

    cloneFields(obj: any) {
        for (const prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                this[prop] = obj[prop]?.map(child => { // You have to check it is an array or not,..
                    const c = new (Map[prop])();
                    c.cloneFields(child);
                    return c;
                });
            }
        }
    }
}

You can serialize hints into that JSON. Eg. property type with source/target type name and use it to resolve right types.

3. Reflection

Try tst-reflect. It is pretty advanced Reflection system for TypeScript (using custom typescript transformer plugin).

I'm not going to write example, it would be too complex and it depends on your needs.

You can use tst-reflect to list type's properties and get their types. So you'll be able to validace parsed data too.

Just some showcase from its README:

import { getType } from "tst-reflect";

function printTypeProperties<TType>()
{
    const type = getType<TType>(); // <<== get type of generic TType ;)

    console.log(type.getProperties().map(prop => prop.name + ": " + prop.type.name).join("\n"));
}

interface SomeType {
    foo: string;
    bar: number;
    baz: Date;
}

printTypeProperties<SomeType>();

// or direct
getType<SomeType>().getProperties();

EDIT:

I created a package ng-custom-transformers that simplifies this a lot. Follow its README.

DEMO

EDIT old:

Usage with Angular

Angular has no direct support of custom transformers/plugins. There is a feature request in the Angular Github repo.

But there is a workaround.

You have to add ngx-build-plus. Run ng add ngx-build-plus.
That package defines "plugins".

Plugins allow you to provide some custom code that modifies your webpack configuration.

So you can create plugin and extend Angular's webpack configuration. But here comes the <s>sun</s> problem. There is no public way to add the transformer. There were AngularCompilerPlugin in webpack configuration (@ngtools/webpack) which had private _transformers property. It was possible to add a transformer into that array property. But AngularCompilerPlugin has been replaced by AngularWebpackPlugin which has no such property. But is is possible to override method of AngularWebpackPlugin and add a transformer there. Getting an instance of the AngularWebpackPlugin is possible thanks to ngx-build-plus's plugins.

Code of the plugin

const {AngularWebpackPlugin} = require("@ngtools/webpack");
const tstReflectTransform = require("tst-reflect-transformer").default;

module.exports.default = {
  pre() {},
  post() {},

  config(cfg) {
    // Find the AngularWebpackPlugin in the webpack configuration; angular > 12
    const angularWebpackPlugin = cfg.plugins.find((plugin) => plugin instanceof AngularWebpackPlugin);

    if (!angularWebpackPlugin) {
      console.error("Could not inject the typescript transformer: AngularWebpackPlugin not found");
      return;
    }

    addTransformerToAngularWebpackPlugin(angularWebpackPlugin, transformer);

    return cfg;
  },
};

function transformer(builderProgram) {
  return tstReflectTransform(builderProgram.getProgram());
}

function addTransformerToAngularWebpackPlugin(plugin, transformer) {
  const originalCreateFileEmitter = plugin.createFileEmitter; // private method

  plugin.createFileEmitter = function (programBuilder, transformers, getExtraDependencies, onAfterEmit, ...rest) {
    if (!transformers) {
      transformers = {};
    }

    if (!transformers.before) {
      transformers = {before: []};
    }

    transformers.before = [transformer(programBuilder), ...transformers.before];

    return originalCreateFileEmitter.apply(plugin, [programBuilder, transformers, getExtraDependencies, onAfterEmit, ...rest]);
  };
}

Then it is required to execute ng commands (such as serve or build) with --plugin path/to/the/plugin.js.

I've made working StackBlitz demo.

Resources I've used while preparing the Angular demo:

https://indepth.dev/posts/1045/having-fun-with-angular-and-typescript-transformers

https://medium.com/@morrys/custom-typescript-transformers-with-angular-for-angular-11-12-and-13-40cbdc9cca7b


来源: stackexchange

答:
The solution requires converting to long form, before reshaping into a wide form. One option is a combination of pivot_longer from pyjanitor, with pivot:

# pip install pyjanitor
import pandas as pd
import janitor

( df
.pivot_longer(index='Year', names_to=('col', '.value'), names_sep='_')
.pivot(index='col', columns='Year')
.rename_axis(columns=[None, None])
)

          a                    b
       2017   2018   2019   2017   2018   2019
col
col1    1.4    1.5    0.6  123.0  456.0  789.0
col2  555.0  444.0  333.0   55.5   56.5   57.5
col3    5.0    6.0    8.0   80.0   90.0  100.0
```

ContentLicense: CC BY-SA 4.0

Title: pandas convert columns with same name but different suffixes to indices and index to columns

Body:
I have a problem in which I am trying to change the shape of data, but trying to have column names on row level without having suffixes attached to them.

e.g.

My original df looks like this

+------+--------+--------+--------+--------+--------+--------+
| Year | col1_a | col2_a | col3_a | col1_b | col2_b | col3_b |
+------+--------+--------+--------+--------+--------+--------+
| 2017 |    1.4 |    555 |      5 |    123 |   55.5 |     80 |
| 2018 |    1.5 |    444 |      6 |    456 |   56.5 |     90 |
| 2019 |    0.6 |    333 |      8 |    789 |   57.5 |    100 |
+------+--------+--------+--------+--------+--------+--------+

and I am trying to reshape it as

+------+------+------+------+------+------+------+
|      |  a   |  a   |   a  |  b   |   b  |   b  |
+------+------+------+------+------+------+------+
|        2017 | 2018 | 2019 | 2017 | 2018 | 2019 |
| col1 |  1.4 |  1.5 |  0.6 |  123 |  456 |  789 |
| col2 |  555 |  444 |  333 | 55.5 | 56.5 | 57.5 |
| col3 |    5 |    6 |    8 |   80 |   90 |  100 |
+------+------+------+------+------+------+------+

I can use pivot_table but the thing is I am not able to get unique column names at index level. Any idea which method can be used to reshape this?


问:
Issues I have with making a navbar in CSS
I tried adding a navbar, and I use this.

.topnav {
  background-color: rgb(0, 0, 0);
  overflow: hidden;
  width: 1920;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.topnav a {
  position: relative;
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 7px 16px;
  text-decoration: none;
  font-size: 17px;
  transition: .5s;
  border-radius: 30px;
}

.topnav a:hover {
  background-color: #b0fcbd;
  color: black;
  border-radius: 30px;
  padding: 7px 16px;
  opacity: 70%;
}

.topnav a.active {
  background-color: #21ff46;
  color: black;
  border-radius: 30px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="topnav">
  Home
  News
  Contact
  About
</div></code>```

Yet, the navbar (the blackest part - the background is a bit lighter) starts out a few pixels below and to the right of when the page starts. Also, the Links are in the complete middle. I just want them centered at the top. Hope someone can help.

答:
Is this what you were looking for?

The extra pixels at the top / around the page are part of the default css that different browsers set

You can remove that with margin:0 on body

.topnav {
  background-color: rgb(0, 0, 0);
  overflow: hidden;
  height: 200px;
  display: flex;
  align-items: start;
  justify-content: center;
}

body {
  margin:0;
}

.topnav a {
  position: relative;
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 7px 16px;
  text-decoration: none;
  font-size: 17px;
  transition: .5s;
  border-radius: 30px;
}

.topnav a:hover {
  background-color: #b0fcbd;
  color: black;
  border-radius: 30px;
  padding: 7px 16px;
  opacity: 70%;
}

.topnav a.active {
  background-color: #21ff46;
  color: black;
  border-radius: 30px;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="topnav">
  Home
  News
  Contact
  About
</div></code>```

Body:
I tried adding a navbar, and I use this.

.topnav {
  background-color: rgb(0, 0, 0);
  overflow: hidden;
  width: 1920;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.topnav a {
  position: relative;
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 7px 16px;
  text-decoration: none;
  font-size: 17px;
  transition: .5s;
  border-radius: 30px;
}

.topnav a:hover {
  background-color: #b0fcbd;
  color: black;
  border-radius: 30px;
  padding: 7px 16px;
  opacity: 70%;
}

.topnav a.active {
  background-color: #21ff46;
  color: black;
  border-radius: 30px;
}

  Home
  News
  Contact
  About

Yet, the navbar (the blackest part - the background is a bit lighter) starts out a few pixels below and to the right of when the page starts. Also, the Links are in the complete middle. I just want them centered at the top. Hope someone can help.

Body:
Is this what you were looking for?

The extra pixels at the top / around the page are part of the default css that different browsers set

You can remove that with margin:0 on body

.topnav {
  background-color: rgb(0, 0, 0);
  overflow: hidden;
  height: 200px;
  display: flex;
  align-items: start;
  justify-content: center;
}

body {
  margin:0;
}

.topnav a {
  position: relative;
  float: left;
  color: #f2f2f2;
  text-align: center;
  padding: 7px 16px;
  text-decoration: none;
  font-size: 17px;
  transition: .5s;
  border-radius: 30px;
}

.topnav a:hover {
  background-color: #b0fcbd;
  color: black;
  border-radius: 30px;
  padding: 7px 16px;
  opacity: 70%;
}

.topnav a.active {
  background-color: #21ff46;
  color: black;
  border-radius: 30px;
}

<div class="topnav">
  <a class="active" href="#home">Home</a>
  <a href="#news">News</a>
  <a href="#contact">Contact</a>
  <a href="#about">About</a>
</div>


问:
Python code to loop though list of files and read specific line fails after first loop
I'm trying to write a python code to read through a specific line from list of files in a directory and below is my python code. For a practice I kept two csv files in the directory.
I'm reading the second line from each file and if the line is empty I want to print as 'Pass' otherwise as 'Fail'. The code reads the first file which has values in the second row and it prints correctly as 'fail' and that is all the output i'm getting from this code as its not printing anything for the second file. could somebody please help me out here.</p>
```<code>        import os
        from itertools import islice
        for filename in os.listdir(r"input_file_path"):
            f= open(os.path.join(r"input_file_path", filename))
            for line in islice(f,1,2):
                if line == None:
                    print(filename,'pass')
                else:
                    print(filename,'fail')
</code>```

答:
I have check it - your code works correctly.

It looks like you are contradicting yourself:

...and if the line is empty I want to print as 'fail' otherwise as
'pass'

The code reads the first file which has values in the second row and
it prints correctly as 'fail'

Check contents of the files you are reading in.
You could also put some print statements inside your code to be sure what exactly is happening during the program execution (e.g. which files are being read, what is the content of each line, etc).

Body:
I'm trying to write a python code to read through a specific line from list of files in a directory and below is my python code. For a practice I kept two csv files in the directory.
I'm reading the second line from each file and if the line is empty I want to print as 'Pass' otherwise as 'Fail'. The code reads the first file which has values in the second row and it prints correctly as 'fail' and that is all the output i'm getting from this code as its not printing anything for the second file. could somebody please help me out here.

        import os
        from itertools import islice
        for filename in os.listdir(r"input_file_path"):
            f= open(os.path.join(r"input_file_path", filename))
            for line in islice(f,1,2):
                if line == None:
                    print(filename,'pass')
                else:
                    print(filename,'fail')


问:
Python dictionary not getting updated
Hello I have below code where I am trying to add elements to a dict

```<code>for ent in NACLS:
    set_filter = {'Name': 'network-acl-id', 'Values': [naclID]}
    print(set_filter)
    set_filter.update({'Name': 'entry.rule-number', 'Values': [str(ent[0])]})
    print(set_filter)
</code>```

The output for the above code is

```<code>{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['50']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['60']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['70']}
</code>```

Whereas I was wanting it to update the existing dictionary but somehow it's getting overwritten. Expected output

```<code>{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['50']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['60']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['70']}
</code>```

can someone please guide me on how I can achieve this?

答:
I don't understand much about your purpose of the list of dictionary, the suggested code

set_filters = []
for ent in NACLS:
    set_filters.append({'Name': 'network-acl-id', 'Values': [naclID]})
    set_filters.append({'Name': 'entry.rule-number', 'Values': [str(ent[0])]})
```
<p>is close to your idea. However, the two dictionaries you tried to gather in the list can be combined into just one:</p>
<pre class="lang-py prettyprint-override"><code>set_filters = []
for ent in NACLS:
    set_filters.append(
        {
            'network-acl-id': [naclID],
            'entry.rule-number': [str(ent[0])]
        }
    )
</code>```

From here, you can make it shorter as

set_filters = [
    { 'network-acl-id': [naclID], 'entry.rule-number': [str(ent[0])] } for ent in NACLS
]
```

Title: Python dictionary not getting updated

Body:
Hello I have below code where I am trying to add elements to a dict

for ent in NACLS:
    set_filter = {'Name': 'network-acl-id', 'Values': [naclID]}
    print(set_filter)
    set_filter.update({'Name': 'entry.rule-number', 'Values': [str(ent[0])]})
    print(set_filter)

The output for the above code is

{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['50']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['60']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}
{'Name': 'entry.rule-number', 'Values': ['70']}

Whereas I was wanting it to update the existing dictionary but somehow it's getting overwritten. Expected output

{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['50']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['60']}
{'Name': 'network-acl-id', 'Values': ['acl-08128a2540eb']}, {'Name': 'entry.rule-number', 'Values': ['70']}

can someone please guide me on how I can achieve this?

Body:
I don't understand much about your purpose of the list of dictionary, the suggested code

set_filters = []
for ent in NACLS:
    set_filters.append({'Name': 'network-acl-id', 'Values': [naclID]})
    set_filters.append({'Name': 'entry.rule-number', 'Values': [str(ent[0])]})

is close to your idea. However, the two dictionaries you tried to gather in the list can be combined into just one:

set_filters = []
for ent in NACLS:
    set_filters.append(
        {
            'network-acl-id': [naclID],
            'entry.rule-number': [str(ent[0])]
        }
    )

From here, you can make it shorter as

set_filters = [
    { 'network-acl-id': [naclID], 'entry.rule-number': [str(ent[0])] } for ent in NACLS
]


问:
Creating framework in XCode
I am creating a framework in XCode 4. I made this header public (SkypeListener.h):

```<code>#import <Foundation/Foundation.h>
#import <Skype/Skype.h>

void start();
void stop();

@interface SkypeListener : NSObject <SkypeAPIDelegate>

- (void)start;
- (void)stop;

@end
</code>```

The framework is called SkypeTestFramework. Now to test this framework and I setup a new project, dragged SkypeTestFramework into the frameworks folder and imported:

```<code>#import <SkypeTestFramework/SkypeListener.h>
</code>```

But I get this error:

```<code>/Users/****/Desktop/testskype/SkypeTestFramework.framework/Headers/SkypeListener.h:10:9: fatal error: 'Skype/Skype.h' file not found [1]
</code>```

What am I doing wrong? Thanks.

Oh also, in SkypeTestFramework, I am using a framework called Skype.framework. Could it be that, that's causing the problem?
Thanks.

答: If you created Skype/Skype.h, would write it like:  import "Skype/Skype.h".  But you would need to include the full path if it not part of your current project.

ContentLicense: CC BY-SA 3.0

Title: Creating framework in XCode

Body:
I am creating a framework in XCode 4. I made this header public (SkypeListener.h):

#import <Foundation/Foundation.h>
#import <Skype/Skype.h>

void start();
void stop();

@interface SkypeListener : NSObject <SkypeAPIDelegate>

- (void)start;
- (void)stop;

@end

The framework is called SkypeTestFramework. Now to test this framework and I setup a new project, dragged SkypeTestFramework into the frameworks folder and imported:

#import <SkypeTestFramework/SkypeListener.h>

But I get this error:

/Users/****/Desktop/testskype/SkypeTestFramework.framework/Headers/SkypeListener.h:10:9: fatal error: 'Skype/Skype.h' file not found [1]

What am I doing wrong? Thanks.

Oh also, in SkypeTestFramework, I am using a framework called Skype.framework. Could it be that, that's causing the problem?
Thanks.


答:
As you appear to be using Markdown as your current output format, you can use the python-markdown package to convert it to HTML.

There are also tutorials on how to do that, for example How To Use Python-Markdown to Convert Markdown Text to HTML

Title: How can I generate an HTML report in python?

Body:
I have written a python script that shows the differences in the repo branches of GitLab using GitLab API. Now my task is to write an HTML report to this script. I referred to many pages but I did not understand how and where exactly I can start?

My script output is like:

Listing Differences Between Branches: main and branch1

No Reference found in :
second project
newpro

Nothing to compare in :
third project

Following are repos with changes :

fourth project
+------+-------------------+------------------+-------------------------------------------------------------------------------------------------+------------+----------+
| S.NO |   Commit Message  |      Author      |                                               URL                                               |    Date    |   Time   |
+------+-------------------+------------------+-------------------------------------------------------------------------------------------------+------------+----------+
|  1   | added second line | Ganesh Thirumani | https://gitlab.com/mygroup1316/fourth-project/-/commit/39e8806f364827544683934e3967c321f3b21678 | 2022-02-08 | 10:18:48 |
|  2   |  added third line | Ganesh Thirumani | https://gitlab.com/mygroup1316/fourth-project/-/commit/3f3a9ed7d1ab8fa4e6bb7ae6fa68c3b97b1f94b4 | 2022-02-08 | 11:13:20 |
|  3   |  added third line | Ganesh Thirumani | https://gitlab.com/mygroup1316/fourth-project/-/commit/f75946ce53b78669dbe813d8f3f2402f276ec862 | 2022-02-08 | 12:15:13 |
+------+-------------------+------------------+-------------------------------------------------------------------------------------------------+------------+----------+

first_project
+------+------------------+------------------+------------------------------------------------------------------------------------------------+------------+----------+
| S.NO |  Commit Message  |      Author      |                                              URL                                               |    Date    |   Time   |
+------+------------------+------------------+------------------------------------------------------------------------------------------------+------------+----------+
|  1   |  latest commit   | Ganesh Thirumani | https://gitlab.com/mygroup1316/first_project/-/commit/a39c795bfd0699343d956098023b21527192532f | 2022-02-07 | 04:47:40 |
|  2   | latest commit1.0 | Ganesh Thirumani | https://gitlab.com/mygroup1316/first_project/-/commit/b596f57b830d5c0c2f9b491f836a5974b65bcdba | 2022-02-07 | 06:06:20 |
+------+------------------+------------------+------------------------------------------------------------------------------------------------+------------+----------+

How can I make an HTML report to this output and where do I start?
and also Do I need to learn all the HTML to write this?

Thanks in advance...


问:
Jackson ObjectMapper JSON Error UnrecognizedPropertyException
I'm trying to learn the process of packaging. While using the Jackson ObjectMapper to parse my JSON file, I receive an UnrecognizedPropertyException.

```<code>com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa" (class com.stateparser.database.StateGroup), not marked as ignorable (one known property: "states"])
 at [Source: (File); line: 2, column: 11] (through reference chain: com.stateparser.database.StateGroup["usa"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1127)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1989)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1700)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1678)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:319)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3494)
    at com.stateparser.Main.main(Main.java:20)
</code>```

I'm not sure where I created the error. I was attempting to create a list of state objects. With the list of object, loop through it and print the data for each object to the console.

Following the accepted answer of a previous question asked

Jackson ObjectMapper JSON to Java Object RETURNS NULL Values

and the process of packaging by layer; I have laid out my project as follows:

The JSON file which contains the list of States:

```<code>{
  "usa": [
    {
      "abbr": "AL",
      "name": "Alabama",
      "capital": "Montgomery",
      "latitude": "32.361538",
      "longitude": "-86.279118"
    },
    {
      "abbr": "AK",
      "name": "Alaska",
      "capital": "Juneau",
      "latitude": "58.301935",
      "longitude": "-134.419740"
    },
    {
      "abbr": "AZ",
      "name": "Arizona",
      "capital": "Phoenix",
      "latitude": "33.448457",
      "longitude": "-112.073844"
    },
    {
      "abbr": "AR",
      "name": "Arkansas",
      "capital": "Little Rock",
      "latitude": "34.736009",
      "longitude": "-92.331122"
    },
    {
      "abbr": "CA",
      "name": "California",
      "capital": "Sacramento",
      "latitude": "38.555605",
      "longitude": "-121.468926"
    },
    {
      "abbr": "CO",
      "name": "Colorado",
      "capital": "Denver",
      "latitude": "39.7391667",
      "longitude": "-104.984167"
    },
    {
      "abbr": "CT",
      "name": "Connecticut",
      "capital": "Hartford",
      "latitude": "41.767",
      "longitude": "-72.677"
    },
    {
      "abbr": "DE",
      "name": "Delaware",
      "capital": "Dover",
      "latitude": "39.161921",
      "longitude": "-75.526755"
    },
    {
      "abbr": "FL",
      "name": "Florida",
      "capital": "Tallahassee",
      "latitude": "30.4518",
      "longitude": "-84.27277"
    },
    {
      "abbr": "GA",
      "name": "Georgia",
      "capital": "Atlanta",
      "latitude": "33.76",
      "longitude": "-84.39"
    },
    {
      "abbr": "HI",
      "name": "Hawaii",
      "capital": "Honolulu",
      "latitude": "21.30895",
      "longitude": "-157.826182"
    },
    {
      "abbr": "ID",
      "name": "Idaho",
      "capital": "Boise",
      "latitude": "43.613739",
      "longitude": "-116.237651"
    },
    {
      "abbr": "IL",
      "name": "Illinois",
      "capital": "Springfield",
      "latitude": "39.783250",
      "longitude": "-89.650373"
    },
    {
      "abbr": "IN",
      "name": "Indiana",
      "capital": "Indianapolis",
      "latitude": "39.790942",
      "longitude": "-86.147685"
    },
    {
      "abbr": "IA",
      "name": "Iowa",
      "capital": "Des Moines",
      "latitude": "41.590939",
      "longitude": "-93.620866"
    },
    {
      "abbr": "KS",
      "name": "Kansas",
      "capital": "Topeka",
      "latitude": "39.04",
      "longitude": "-95.69"
    },
    {
      "abbr": "KY",
      "name": "Kentucky",
      "capital": "Frankfort",
      "latitude": "38.197274",
      "longitude": "-84.86311"
    },
    {
      "abbr": "LA",
      "name": "Louisiana",
      "capital": "Baton Rouge",
      "latitude": "30.45809",
      "longitude": "-91.140229"
    },
    {
      "abbr": "ME",
      "name": "Maine",
      "capital": "Augusta",
      "latitude": "44.323535",
      "longitude": "-69.765261"
    },
    {
      "abbr": "MD",
      "name": "Maryland",
      "capital": "Annapolis",
      "latitude": "38.972945",
      "longitude": "-76.501157"
    },
    {
      "abbr": "MA",
      "name": "Massachusetts",
      "capital": "Boston",
      "latitude": "42.2352",
      "longitude": "-71.0275"
    },
    {
      "abbr": "MI",
      "name": "Michigan",
      "capital": "Lansing",
      "latitude": "42.7335",
      "longitude": "-84.5467"
    },
    {
      "abbr": "MN",
      "name": "Minnesota",
      "capital": "Saint Paul",
      "latitude": "44.95",
      "longitude": "-93.094"
    },
    {
      "abbr": "MS",
      "name": "Mississippi",
      "capital": "Jackson",
      "latitude": "32.320",
      "longitude": "-90.207"
    },
    {
      "abbr": "MO",
      "name": "Missouri",
      "capital": "Jefferson City",
      "latitude": "38.572954",
      "longitude": "-92.189283"
    },
    {
      "abbr": "MT",
      "name": "Montana",
      "capital": "Helana",
      "latitude": "46.595805",
      "longitude": "-112.027031"
    },
    {
      "abbr": "NE",
      "name": "Nebraska",
      "capital": "Lincoln",
      "latitude": "40.809868",
      "longitude": "-96.675345"
    },
    {
      "abbr": "NV",
      "name": "Nevada",
      "capital": "Carson City",
      "latitude": "39.160949",
      "longitude": "-119.753877"
    },
    {
      "abbr": "NH",
      "name": "New Hampshire",
      "capital": "Concord",
      "latitude": "43.220093",
      "longitude": "-71.549127"
    },
    {
      "abbr": "NJ",
      "name": "New Jersey",
      "capital": "Trenton",
      "latitude": "40.221741",
      "longitude": "-74.756138"
    },
    {
      "abbr": "NM",
      "name": "New Mexico",
      "capital": "Santa Fe",
      "latitude": "35.667231",
      "longitude": "-105.964575"
    },
    {
      "abbr": "NY",
      "name": "New York",
      "capital": "Albany",
      "latitude": "42.659829",
      "longitude": "-73.781339"
    },
    {
      "abbr": "NC",
      "name": "North Carolina",
      "capital": "Raleigh",
      "latitude": "35.771",
      "longitude": "-78.638"
    },
    {
      "abbr": "ND",
      "name": "North Dakota",
      "capital": "Bismarck",
      "latitude": "48.813343",
      "longitude": "-100.779004"
    },
    {
      "abbr": "OH",
      "name": "Ohio",
      "capital": "Columbus",
      "latitude": "39.962245",
      "longitude": "-83.000647"
    },
    {
      "abbr": "OK",
      "name": "Oklahoma",
      "capital": "Oklahoma City",
      "latitude": "35.482309",
      "longitude": "-97.534994"
    },
    {
      "abbr": "OR",
      "name": "Oregon",
      "capital": "Salem",
      "latitude": "44.931109",
      "longitude": "-123.029159"
    },
    {
      "abbr": "PA",
      "name": "Pennsylvania",
      "capital": "Harrisburg",
      "latitude": "40.269789",
      "longitude": "-76.875613"
    },
    {
      "abbr": "RI",
      "name": "Rhode Island",
      "capital": "Providence",
      "latitude": "41.82355",
      "longitude": "-71.422132"
    },
    {
      "abbr": "SC",
      "name": "South Carolina",
      "capital": "Columbia",
      "latitude": "34.000",
      "longitude": "-81.035"
    },
    {
      "abbr": "SD",
      "name": "South Dakota",
      "capital": "Pierre",
      "latitude": "44.367966",
      "longitude": "-100.336378"
    },
    {
      "abbr": "TN",
      "name": "Tennessee",
      "capital": "Nashville",
      "latitude": "36.165",
      "longitude": "-86.784"
    },
    {
      "abbr": "TX",
      "name": "Texas",
      "capital": "Austin",
      "latitude": "30.266667",
      "longitude": "-97.75"
    },
    {
      "abbr": "UT",
      "name": "Utah",
      "capital": "Salt Lake City",
      "latitude": "40.7547",
      "longitude": "-111.892622"
    },
    {
      "abbr": "VT",
      "name": "Vermont",
      "capital": "Montpelier",
      "latitude": "44.26639",
      "longitude": "-72.57194"
    },
    {
      "abbr": "VA",
      "name": "Virginia",
      "capital": "Richmond",
      "latitude": "37.54",
      "longitude": "-77.46"
    },
    {
      "abbr": "WA",
      "name": "Washington",
      "capital": "Olympia",
      "latitude": "47.042418",
      "longitude": "-122.893077"
    },
    {
      "abbr": "WV",
      "name": "West Virginia",
      "capital": "Charleston",
      "latitude": "38.349497",
      "longitude": "-81.633294"
    },
    {
      "abbr": "WI",
      "name": "Wisconsin",
      "capital": "Madison",
      "latitude": "43.074722",
      "longitude": "-89.384444"
    },
    {
      "abbr": "WY",
      "name": "Wyoming",
      "capital": "Cheyenne",
      "latitude": "41.145548",
      "longitude": "-104.802042"
    }
  ]
}
</code>```

The Java class file which describes a state:

```<code>package com.stateparser.database;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class State {
    private String abbr;
    private String name;
    private String capital;
    private String latitude;
    private String longitude;

    public State() {
        // DEFAULT CONSTRUCTOR
    }

    public State(String abbr, String name, String capital, String latitude, String longitude) {
        this.abbr = abbr;
        this.name = name;
        this.capital = capital;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return name + "{" +
                "name='" + name + "'" +
                "capital='" + capital + "'" +
                "abbr='" + abbr + "'" +
                "latitude='" + latitude + "'" +
                "longitude='" + longitude + "'}";
    }

    public String getAbbr() {
        return abbr;
    }

    public void setAbbr(String abbr) {
        this.abbr = abbr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCapital() {
        return capital;
    }

    public void setCapital(String capital) {
        this.capital = capital;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }
}
</code>```

The Java class which creates a list of objects based on my state class:

```<code>package com.stateparser.database;

import java.util.List;

public class StateGroup {
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}
</code>```

The main Java class:

```<code>package com.stateparser;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.stateparser.database.State;
import com.stateparser.database.StateGroup;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        File file = new File("src/main/resources/States.json");

        ObjectMapper mapper = new ObjectMapper();

        try {
            StateGroup States = mapper.readValue(file, StateGroup.class);

            List<State> allTerritories = States.getStates();

            allTerritories.forEach(states -> {
                System.out.println(states);
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
</code>```

I'm looking for some help to understand why I receive the UnrecognizedPropertyException.

答:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa"

You are trying to map the JSON to the StateGroup object, but the Java object doesn't have a "usa" field.

Two options:

Rename the states field to usa:

```<code>public class StateGroup {
    private List<State> usa;

    public List<State> getUsa() {
        return usa;
    }

    public void setUsa(List<State> usa) {
        this.usa = usa;
    }
}
</code>```

Add the @JsonProperty("usa") annotation to the states field:

```<code>import com.fasterxml.jackson.annotation.JsonProperty;

public class StateGroup {
    @JsonProperty("usa")
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}
</code>```

Body:
I'm trying to learn the process of packaging. While using the Jackson ObjectMapper to parse my JSON file, I receive an UnrecognizedPropertyException.

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa" (class com.stateparser.database.StateGroup), not marked as ignorable (one known property: "states"])
 at [Source: (File); line: 2, column: 11] (through reference chain: com.stateparser.database.StateGroup["usa"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1127)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1989)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1700)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1678)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:319)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3494)
    at com.stateparser.Main.main(Main.java:20)

I'm not sure where I created the error. I was attempting to create a list of state objects. With the list of object, loop through it and print the data for each object to the console.

Following the accepted answer of a previous question asked

Jackson ObjectMapper JSON to Java Object RETURNS NULL Values

and the process of packaging by layer; I have laid out my project as follows:

The JSON file which contains the list of States:

{
  "usa": [
    {
      "abbr": "AL",
      "name": "Alabama",
      "capital": "Montgomery",
      "latitude": "32.361538",
      "longitude": "-86.279118"
    },
    {
      "abbr": "AK",
      "name": "Alaska",
      "capital": "Juneau",
      "latitude": "58.301935",
      "longitude": "-134.419740"
    },
    {
      "abbr": "AZ",
      "name": "Arizona",
      "capital": "Phoenix",
      "latitude": "33.448457",
      "longitude": "-112.073844"
    },
    {
      "abbr": "AR",
      "name": "Arkansas",
      "capital": "Little Rock",
      "latitude": "34.736009",
      "longitude": "-92.331122"
    },
    {
      "abbr": "CA",
      "name": "California",
      "capital": "Sacramento",
      "latitude": "38.555605",
      "longitude": "-121.468926"
    },
    {
      "abbr": "CO",
      "name": "Colorado",
      "capital": "Denver",
      "latitude": "39.7391667",
      "longitude": "-104.984167"
    },
    {
      "abbr": "CT",
      "name": "Connecticut",
      "capital": "Hartford",
      "latitude": "41.767",
      "longitude": "-72.677"
    },
    {
      "abbr": "DE",
      "name": "Delaware",
      "capital": "Dover",
      "latitude": "39.161921",
      "longitude": "-75.526755"
    },
    {
      "abbr": "FL",
      "name": "Florida",
      "capital": "Tallahassee",
      "latitude": "30.4518",
      "longitude": "-84.27277"
    },
    {
      "abbr": "GA",
      "name": "Georgia",
      "capital": "Atlanta",
      "latitude": "33.76",
      "longitude": "-84.39"
    },
    {
      "abbr": "HI",
      "name": "Hawaii",
      "capital": "Honolulu",
      "latitude": "21.30895",
      "longitude": "-157.826182"
    },
    {
      "abbr": "ID",
      "name": "Idaho",
      "capital": "Boise",
      "latitude": "43.613739",
      "longitude": "-116.237651"
    },
    {
      "abbr": "IL",
      "name": "Illinois",
      "capital": "Springfield",
      "latitude": "39.783250",
      "longitude": "-89.650373"
    },
    {
      "abbr": "IN",
      "name": "Indiana",
      "capital": "Indianapolis",
      "latitude": "39.790942",
      "longitude": "-86.147685"
    },
    {
      "abbr": "IA",
      "name": "Iowa",
      "capital": "Des Moines",
      "latitude": "41.590939",
      "longitude": "-93.620866"
    },
    {
      "abbr": "KS",
      "name": "Kansas",
      "capital": "Topeka",
      "latitude": "39.04",
      "longitude": "-95.69"
    },
    {
      "abbr": "KY",
      "name": "Kentucky",
      "capital": "Frankfort",
      "latitude": "38.197274",
      "longitude": "-84.86311"
    },
    {
      "abbr": "LA",
      "name": "Louisiana",
      "capital": "Baton Rouge",
      "latitude": "30.45809",
      "longitude": "-91.140229"
    },
    {
      "abbr": "ME",
      "name": "Maine",
      "capital": "Augusta",
      "latitude": "44.323535",
      "longitude": "-69.765261"
    },
    {
      "abbr": "MD",
      "name": "Maryland",
      "capital": "Annapolis",
      "latitude": "38.972945",
      "longitude": "-76.501157"
    },
    {
      "abbr": "MA",
      "name": "Massachusetts",
      "capital": "Boston",
      "latitude": "42.2352",
      "longitude": "-71.0275"
    },
    {
      "abbr": "MI",
      "name": "Michigan",
      "capital": "Lansing",
      "latitude": "42.7335",
      "longitude": "-84.5467"
    },
    {
      "abbr": "MN",
      "name": "Minnesota",
      "capital": "Saint Paul",
      "latitude": "44.95",
      "longitude": "-93.094"
    },
    {
      "abbr": "MS",
      "name": "Mississippi",
      "capital": "Jackson",
      "latitude": "32.320",
      "longitude": "-90.207"
    },
    {
      "abbr": "MO",
      "name": "Missouri",
      "capital": "Jefferson City",
      "latitude": "38.572954",
      "longitude": "-92.189283"
    },
    {
      "abbr": "MT",
      "name": "Montana",
      "capital": "Helana",
      "latitude": "46.595805",
      "longitude": "-112.027031"
    },
    {
      "abbr": "NE",
      "name": "Nebraska",
      "capital": "Lincoln",
      "latitude": "40.809868",
      "longitude": "-96.675345"
    },
    {
      "abbr": "NV",
      "name": "Nevada",
      "capital": "Carson City",
      "latitude": "39.160949",
      "longitude": "-119.753877"
    },
    {
      "abbr": "NH",
      "name": "New Hampshire",
      "capital": "Concord",
      "latitude": "43.220093",
      "longitude": "-71.549127"
    },
    {
      "abbr": "NJ",
      "name": "New Jersey",
      "capital": "Trenton",
      "latitude": "40.221741",
      "longitude": "-74.756138"
    },
    {
      "abbr": "NM",
      "name": "New Mexico",
      "capital": "Santa Fe",
      "latitude": "35.667231",
      "longitude": "-105.964575"
    },
    {
      "abbr": "NY",
      "name": "New York",
      "capital": "Albany",
      "latitude": "42.659829",
      "longitude": "-73.781339"
    },
    {
      "abbr": "NC",
      "name": "North Carolina",
      "capital": "Raleigh",
      "latitude": "35.771",
      "longitude": "-78.638"
    },
    {
      "abbr": "ND",
      "name": "North Dakota",
      "capital": "Bismarck",
      "latitude": "48.813343",
      "longitude": "-100.779004"
    },
    {
      "abbr": "OH",
      "name": "Ohio",
      "capital": "Columbus",
      "latitude": "39.962245",
      "longitude": "-83.000647"
    },
    {
      "abbr": "OK",
      "name": "Oklahoma",
      "capital": "Oklahoma City",
      "latitude": "35.482309",
      "longitude": "-97.534994"
    },
    {
      "abbr": "OR",
      "name": "Oregon",
      "capital": "Salem",
      "latitude": "44.931109",
      "longitude": "-123.029159"
    },
    {
      "abbr": "PA",
      "name": "Pennsylvania",
      "capital": "Harrisburg",
      "latitude": "40.269789",
      "longitude": "-76.875613"
    },
    {
      "abbr": "RI",
      "name": "Rhode Island",
      "capital": "Providence",
      "latitude": "41.82355",
      "longitude": "-71.422132"
    },
    {
      "abbr": "SC",
      "name": "South Carolina",
      "capital": "Columbia",
      "latitude": "34.000",
      "longitude": "-81.035"
    },
    {
      "abbr": "SD",
      "name": "South Dakota",
      "capital": "Pierre",
      "latitude": "44.367966",
      "longitude": "-100.336378"
    },
    {
      "abbr": "TN",
      "name": "Tennessee",
      "capital": "Nashville",
      "latitude": "36.165",
      "longitude": "-86.784"
    },
    {
      "abbr": "TX",
      "name": "Texas",
      "capital": "Austin",
      "latitude": "30.266667",
      "longitude": "-97.75"
    },
    {
      "abbr": "UT",
      "name": "Utah",
      "capital": "Salt Lake City",
      "latitude": "40.7547",
      "longitude": "-111.892622"
    },
    {
      "abbr": "VT",
      "name": "Vermont",
      "capital": "Montpelier",
      "latitude": "44.26639",
      "longitude": "-72.57194"
    },
    {
      "abbr": "VA",
      "name": "Virginia",
      "capital": "Richmond",
      "latitude": "37.54",
      "longitude": "-77.46"
    },
    {
      "abbr": "WA",
      "name": "Washington",
      "capital": "Olympia",
      "latitude": "47.042418",
      "longitude": "-122.893077"
    },
    {
      "abbr": "WV",
      "name": "West Virginia",
      "capital": "Charleston",
      "latitude": "38.349497",
      "longitude": "-81.633294"
    },
    {
      "abbr": "WI",
      "name": "Wisconsin",
      "capital": "Madison",
      "latitude": "43.074722",
      "longitude": "-89.384444"
    },
    {
      "abbr": "WY",
      "name": "Wyoming",
      "capital": "Cheyenne",
      "latitude": "41.145548",
      "longitude": "-104.802042"
    }
  ]
}

The Java class file which describes a state:

package com.stateparser.database;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class State {
    private String abbr;
    private String name;
    private String capital;
    private String latitude;
    private String longitude;

    public State() {
        // DEFAULT CONSTRUCTOR
    }

    public State(String abbr, String name, String capital, String latitude, String longitude) {
        this.abbr = abbr;
        this.name = name;
        this.capital = capital;
        this.latitude = latitude;
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return name + "{" +
                "name='" + name + "'" +
                "capital='" + capital + "'" +
                "abbr='" + abbr + "'" +
                "latitude='" + latitude + "'" +
                "longitude='" + longitude + "'}";
    }

    public String getAbbr() {
        return abbr;
    }

    public void setAbbr(String abbr) {
        this.abbr = abbr;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCapital() {
        return capital;
    }

    public void setCapital(String capital) {
        this.capital = capital;
    }

    public String getLatitude() {
        return latitude;
    }

    public void setLatitude(String latitude) {
        this.latitude = latitude;
    }

    public String getLongitude() {
        return longitude;
    }

    public void setLongitude(String longitude) {
        this.longitude = longitude;
    }
}

The Java class which creates a list of objects based on my state class:

package com.stateparser.database;

import java.util.List;

public class StateGroup {
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}

The main Java class:

package com.stateparser;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.stateparser.database.State;
import com.stateparser.database.StateGroup;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        File file = new File("src/main/resources/States.json");

        ObjectMapper mapper = new ObjectMapper();

        try {
            StateGroup States = mapper.readValue(file, StateGroup.class);

            List<State> allTerritories = States.getStates();

            allTerritories.forEach(states -> {
                System.out.println(states);
            });
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I'm looking for some help to understand why I receive the UnrecognizedPropertyException.

Body:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "usa"

You are trying to map the JSON to the StateGroup object, but the Java object doesn't have a "usa" field.

Two options:

Rename the states field to usa:

public class StateGroup {
    private List<State> usa;

    public List<State> getUsa() {
        return usa;
    }

    public void setUsa(List<State> usa) {
        this.usa = usa;
    }
}

Add the @JsonProperty("usa") annotation to the states field:

import com.fasterxml.jackson.annotation.JsonProperty;

public class StateGroup {
    @JsonProperty("usa")
    private List<State> states;

    public List<State> getStates() {
        return states;
    }

    public void setStates(List<State> states) {
        this.states = states;
    }
}


问:
SwiftUI List: Prevent Empty Selection
I have a SwiftUI list, defined in a typical fashion:

```<code>struct SettingsView: View
{
    @State private var selectedCategory: SettingsCategory? = .general

    List(SettingsCategory.allCases, id: \.self, selection: $selectedCategory) { category in
        [...]
    }
}
</code>```

In this case, the List is a table of "categories" for a settings area in my UI. The SettingsCategory is an enum that defines these categories, and the UI ends up looking like this:

It is not appropriate for this list to have an empty selection; a category should always be selected. In AppKit, it was trivially easy to disable an empty selection on NSTableView. But in SwiftUI, I've been unable to find a way to disable it. Anytime I click in the empty area of the list, the selection is cleared. How can I stop that?

selectedCategory must be an Optional or the compiler vomits all over itself.

I can't use willSet/didSet on selectedCategory because of the @State property wrapper. And I can't use a computed property that never returns nil because the List's selection has to be bound.

I also tried this approach: SwiftUI DatePicker Binding optional Date, valid nil

So, what magical incantation is required to disable empty selection in List?

答:
you could try adding .onChange to the List, such as:

```<code>.onChange(of: selectedCategory) { val in
    if val == nil {
        selectedCategory = .general // <-- make sure never nil
    }
}
</code>```

Title: SwiftUI List: Prevent Empty Selection

Body:
I have a SwiftUI list, defined in a typical fashion:

struct SettingsView: View
{
    @State private var selectedCategory: SettingsCategory? = .general

    List(SettingsCategory.allCases, id: \.self, selection: $selectedCategory) { category in
        [...]
    }
}

In this case, the List is a table of "categories" for a settings area in my UI. The SettingsCategory is an enum that defines these categories, and the UI ends up looking like this:

It is not appropriate for this list to have an empty selection; a category should always be selected. In AppKit, it was trivially easy to disable an empty selection on NSTableView. But in SwiftUI, I've been unable to find a way to disable it. Anytime I click in the empty area of the list, the selection is cleared. How can I stop that?

selectedCategory must be an Optional or the compiler vomits all over itself.

I can't use willSet/didSet on selectedCategory because of the @State property wrapper. And I can't use a computed property that never returns nil because the List's selection has to be bound.

I also tried this approach: SwiftUI DatePicker Binding optional Date, valid nil

So, what magical incantation is required to disable empty selection in List?

Body:
you could try adding .onChange to the List, such as:

.onChange(of: selectedCategory) { val in
    if val == nil {
        selectedCategory = .general // <-- make sure never nil
    }
}


问:
Gradle: Could not determine java version from '11.0.2'
I ran the following comment:

```<code>./gradlew app:installDebug
</code>```

only to be met with the log:

```<code>FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '11.0.2'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org
</code>```

My version of gradle is 5.1.1:

```<code>------------------------------------------------------------
Gradle 5.1.1
------------------------------------------------------------

Build time:   2019-01-10 23:05:02 UTC
Revision:     3c9abb645fb83932c44e8610642393ad62116807

Kotlin DSL:   1.1.1
Kotlin:       1.3.11
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          11.0.2 (Oracle Corporation 11.0.2+9-LTS)
OS:           Mac OS X 10.13.6 x86_64
</code>```

I'm not sure how to proceed (I tried upgrading/downgrading, but nothing has worked so far).

UPDATE: When I ran ./gradlew --version, I got the following:

```<code>FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '11.0.2'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org
</code>```

My .../gradle/wrapper/gradle-wrapper.properties contains the following including distributionUrl=.../gradle-4.1-rc-1-all.zip:

```<code>distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip
</code>```

答: Navigate to Project/gradle/wrapper/gradle-wrapper.properties and manually changed the distributionUrl to distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip and it worked Hope this helps someone.

Body:
I ran the following comment:

./gradlew app:installDebug

only to be met with the log:

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '11.0.2'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

My version of gradle is 5.1.1:

------------------------------------------------------------
Gradle 5.1.1
------------------------------------------------------------

Build time:   2019-01-10 23:05:02 UTC
Revision:     3c9abb645fb83932c44e8610642393ad62116807

Kotlin DSL:   1.1.1
Kotlin:       1.3.11
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          11.0.2 (Oracle Corporation 11.0.2+9-LTS)
OS:           Mac OS X 10.13.6 x86_64

I'm not sure how to proceed (I tried upgrading/downgrading, but nothing has worked so far).

UPDATE: When I ran ./gradlew --version, I got the following:

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine java version from '11.0.2'.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org

My .../gradle/wrapper/gradle-wrapper.properties contains the following including distributionUrl=.../gradle-4.1-rc-1-all.zip:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-rc-1-all.zip


问:
How to globally specify android and ios are not supported in a .net 5.0 app
I'm using System.IO.Ports in a .net 5.0 project. This generates warnings as follows:

warning CA1416: This call site is reachable on all platforms. 'SerialPort.Close()' is unsupported on: 'ios', 'android'.

I can put guards in to check the platform before calling SerialPort methods, but I calls these in a lot of places.

Instead I was wondering if there was a way to tell .net at the project level that I don't support ios and android.

I don't want to suppress all CA1416 warnings because I do support:

Windows and...

Linux

...and want to be warned if I use something not available on those platforms.

答:
Paraphrasing from the warning documentation;

You can specify multiple "target framework moniker" (TFM) in your projects <TargetFramework> or <TargetFrameworks> tags. If the TFM has a target platform, the .NET SDK injects a SupportedOSPlatform attribute with the targeted platform name in the AssemblyInfo.cs file, which is consumed by the analyzer.

The analyzer doesn't seem to care which frameworks you target, just the SupportedOSPlatform / UnsupportedOSPlatform attributes compiled into your assembly.

While you can't specify a set of target frameworks that would allow windows and linux, but nothing else. That doesn't stop you from defining multiple SupportedOSPlatform attributes in your AssemblyInfo.cs;

using System.Runtime.Versioning;

[assembly: SupportedOSPlatform("windows")]
[assembly: SupportedOSPlatform("linux")]
```

Which I believe should limit how the CA1416 warnings are generated. Even if your project references <TargetFramework>net5.0</TargetFramework>.

Body:
Paraphrasing from the warning documentation;

You can specify multiple "target framework moniker" (TFM) in your projects <TargetFramework> or <TargetFrameworks> tags. If the TFM has a target platform, the .NET SDK injects a SupportedOSPlatform attribute with the targeted platform name in the AssemblyInfo.cs file, which is consumed by the analyzer.

The analyzer doesn't seem to care which frameworks you target, just the SupportedOSPlatform / UnsupportedOSPlatform attributes compiled into your assembly.

While you can't specify a set of target frameworks that would allow windows and linux, but nothing else. That doesn't stop you from defining multiple SupportedOSPlatform attributes in your AssemblyInfo.cs;

using System.Runtime.Versioning;

[assembly: SupportedOSPlatform("windows")]
[assembly: SupportedOSPlatform("linux")]

Which I believe should limit how the CA1416 warnings are generated. Even if your project references <TargetFramework>net5.0</TargetFramework>.


问:
faster way for moving large amounts data in oracle to external database
I have a java program that compares and moves data from a local Oracle database to an external MS SQL data base hosted by an online vendor.

Currently the program connects to the MS SQL database doing a SELECT * FROM myTABLE and putting the results in a two-dimensional array.  A temp table is then created in Oracle and the data is inserted into the temp table using a for loop:

```<code>for (int ii = 0; ii < arr.length(); ii++){
    query = "insert into myTable_temp values "+values_from_array;
    stmt.executeQuery();
}
</code>```

A MINUS statement is used find the differences:

```<code>query = "select * from ora_table minus select * from myTable_temp";
rs = stmt.executeQuery();
</code>```

and the result is then inserted back into the MS SQL table using a insert_into_mssql() method:

```<code>while (rs.next()){
    query = "insert into myTable values "+ values_from_rs
    insert_into_mssql(query);
}
</code>```

This works fine except a table I am using has 220,000 rows.  So it takes a long time to load the array, insert into temp table, run the minus statement, then insert everything back into the mssql table.

Is there a more efficient way to do this? or a way to make this faster?
(a dblink or any direct connection wont work bc of security restrictions)

答:
I would maybe start by not loading it into an array and just using a similar technique as is used in your writing out.  Could also look at parallelizing the inserts.

If I was doing this from scratch, I would bring all the Oracle data to SQL Server and do everything there (copy table from Oracle, find differences and insert into SQL Server, drop the table copied from Oracle) instead of bringing all the SQL Server data to Oracle, dumping just the new records and bringing them over to SQL Server and inserting them.

SQL Server also has a pretty good ETL tool - SQL Server Integration Services, but I haven't had a lot of success using it with things besides SQL Server data sources and destinations.

Body:
I have a java program that compares and moves data from a local Oracle database to an external MS SQL data base hosted by an online vendor.

Currently the program connects to the MS SQL database doing a SELECT * FROM myTABLE and putting the results in a two-dimensional array.  A temp table is then created in Oracle and the data is inserted into the temp table using a for loop:

for (int ii = 0; ii < arr.length(); ii++){
    query = "insert into myTable_temp values "+values_from_array;
    stmt.executeQuery();
}

A MINUS statement is used find the differences:

query = "select * from ora_table minus select * from myTable_temp";
rs = stmt.executeQuery();

and the result is then inserted back into the MS SQL table using a insert_into_mssql() method:

while (rs.next()){
    query = "insert into myTable values "+ values_from_rs
    insert_into_mssql(query);
}

This works fine except a table I am using has 220,000 rows.  So it takes a long time to load the array, insert into temp table, run the minus statement, then insert everything back into the mssql table.

Is there a more efficient way to do this? or a way to make this faster?
(a dblink or any direct connection wont work bc of security restrictions)


问:
Fetch fork of a huge Github repository without redownloading unmodified files
I cloned a repository from Github with this commmand: git clone https://github.com/user1/huge_repo. This repo is huge, multiple gigabytes.

Someone made a small edit to one of the files and pushed their fork on Github. I want to fetch their version of the repo (let's say, it's on https://github.com/user2/huge_repo) without downloading gigabytes of data that are unmodified. Is this possible?

答:
You can use your existing clone as a reference clone.  For instance, if your existing clone lives in $HOME/sources/github.com/user1/huge_repo:

```<code>git clone --reference $HOME/sources/github.com/user1/huge_repo https://github.com/user2/huge_repo
</code>```

You may wish to add --dissociate here, or not; that part is up to you.  With or without --dissociate, your Git asks the GitHub Git what commits they have to send you.  This makes a list of commits to fetch.  Let's assume for concreteness that the list includes a123456.  Your Git now:

looks at the reference clone's objects to see if you already have commit a123456:

if yes, uses the existing copy and tells the other Git no thanks, I already have that commit, which avoids downloading it at all

if no, tells the other Git yes please, send a123456 (which makes it offer the parents of a123456, and we add those to the list of commits to check).

Your Git repeats this for all the commits needed, including those added because your Git said yes, please send that one.  The result is the set of objects you must download, plus a list of hash IDs that you can borrow or steal from the reference clone.

Their Git (GitHub's) packages up the commits and supporting objects that must be sent, knowing which commits your Git has said you already have.  So you get only new objects, not existing ones, and furthermore, those new objects can be delta-compressed against your existing objects.

Now the --dissociate flag comes into play.  If you did not use it, your Git stores, in your user2/huge_repo clone, an "alternates" entry that lists the path name in which the objects you're borrowing live.  The effect of this is that you're now borrowing them for the foreseeable future: some time in the future, you might try to use a commit or supporting object from this clone that you didn't actually clone.  You borrowed it from the reference.

Your Git software will go back to the reference clone and try to use that object from there.  If it's still there, everything works, but if something has happened to that reference clone—such as removing it entirely or merely discarding the referenced object from that clone because it was unused there—then your user2/huge_repo clone may become unusable.  (You can restore the usability by retrieving the missing object, as long as there's some place to get it from.)

If, on the other hand, you did use --dissociate, your Git will, having cloned user2/huge_repo with reference to the reference clone, now copy the reference clone's objects into your new clone.  This means the original reference clone can be removed, or have objects collected out of it, without damaging the new clone.

If you can guarantee that objects won't vanish from the reference clone, you can leave it in place and save disk space—potentially quite a bit.  If not, you'll probably want to spend the disk space up front, to avoid having to repair a broken repository later.

(GitHub work around this kind of problem by never expiring any objects by default.  That's why you have to ask them to remove sensitive data.)

Body:
You can use your existing clone as a reference clone.  For instance, if your existing clone lives in $HOME/sources/github.com/user1/huge_repo:

git clone --reference $HOME/sources/github.com/user1/huge_repo https://github.com/user2/huge_repo

You may wish to add --dissociate here, or not; that part is up to you.  With or without --dissociate, your Git asks the GitHub Git what commits they have to send you.  This makes a list of commits to fetch.  Let's assume for concreteness that the list includes a123456.  Your Git now:

looks at the reference clone's objects to see if you already have commit a123456:

if yes, uses the existing copy and tells the other Git no thanks, I already have that commit, which avoids downloading it at all

if no, tells the other Git yes please, send a123456 (which makes it offer the parents of a123456, and we add those to the list of commits to check).

Your Git repeats this for all the commits needed, including those added because your Git said yes, please send that one.  The result is the set of objects you must download, plus a list of hash IDs that you can borrow or steal from the reference clone.

Their Git (GitHub's) packages up the commits and supporting objects that must be sent, knowing which commits your Git has said you already have.  So you get only new objects, not existing ones, and furthermore, those new objects can be delta-compressed against your existing objects.

Now the --dissociate flag comes into play.  If you did not use it, your Git stores, in your user2/huge_repo clone, an "alternates" entry that lists the path name in which the objects you're borrowing live.  The effect of this is that you're now borrowing them for the foreseeable future: some time in the future, you might try to use a commit or supporting object from this clone that you didn't actually clone.  You borrowed it from the reference.

Your Git software will go back to the reference clone and try to use that object from there.  If it's still there, everything works, but if something has happened to that reference clone—such as removing it entirely or merely discarding the referenced object from that clone because it was unused there—then your user2/huge_repo clone may become unusable.  (You can restore the usability by retrieving the missing object, as long as there's some place to get it from.)

If, on the other hand, you did use --dissociate, your Git will, having cloned user2/huge_repo with reference to the reference clone, now copy the reference clone's objects into your new clone.  This means the original reference clone can be removed, or have objects collected out of it, without damaging the new clone.

If you can guarantee that objects won't vanish from the reference clone, you can leave it in place and save disk space—potentially quite a bit.  If not, you'll probably want to spend the disk space up front, to avoid having to repair a broken repository later.

(GitHub work around this kind of problem by never expiring any objects by default.  That's why you have to ask them to remove sensitive data.)


问:
Is it possible to use a variable containing column names as strings in expressions for creating new data.table columns
Is there an easy way to use a variable containing a data.table column name (string) in the right hand size of an expression that creates a new data.table column?

library(data.table)
mtcars = as.data.table(mtcars)

# Say I have the name of a data.table column stored in a variable
colname = "mpg"

# How could i use this variable to create new columns
# My initial attempt:
mtcars[, `:=` (xMPGBiggerThan20 = colname > 20)]

# I think result is based on "mpg" > 20, rather than using the column values
head(mtcars)
#>     mpg cyl disp  hp drat    wt  qsec vs am gear carb xMPGBiggerThan20
#> 1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4             TRUE
#> 2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4             TRUE
#> 3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1             TRUE
#> 4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1             TRUE
#> 5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2             TRUE
#> 6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1             TRUE

# How would I make the command equivalent to if I wrote
mtcars[, `:=` (xMPGBiggerThan20 = mpg > 20)]

# Desired result
head(mtcars)
#>     mpg cyl disp  hp drat    wt  qsec vs am gear carb xMPGBiggerThan20
#> 1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4             TRUE
#> 2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4             TRUE
#> 3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1             TRUE
#> 4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1             TRUE
#> 5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2            FALSE
#> 6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1            FALSE
```

Created on 2022-02-14 by the reprex package (v2.0.1)

答:
You can try  (data.table 1.14.3)

```<code>mtcars[, xMPGBiggerThan20 := colname > 20, env = list(colname = "mpg")][]
</code>```

or

```<code>mtcars[, `:=` (xMPGBiggerThan20 = colname > 20), env = list(colname = "mpg")][]
</code>```

If you don't want to update to the development version, you can consider to use

```<code>mtcars[, `:=` (xMPGBiggerThan20 = get(colname) > 20)]
</code>```

PS: You can update to the newest version with data.table::update.dev.pkg()

Ref: https://rdatatable.gitlab.io/data.table/articles/datatable-programming.html

Body:
Is there an easy way to use a variable containing a data.table column name (string) in the right hand size of an expression that creates a new data.table column?

library(data.table)
mtcars = as.data.table(mtcars)

# Say I have the name of a data.table column stored in a variable
colname = "mpg"

# How could i use this variable to create new columns
# My initial attempt:
mtcars[, `:=` (xMPGBiggerThan20 = colname > 20)]

# I think result is based on "mpg" > 20, rather than using the column values
head(mtcars)
#>     mpg cyl disp  hp drat    wt  qsec vs am gear carb xMPGBiggerThan20
#> 1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4             TRUE
#> 2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4             TRUE
#> 3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1             TRUE
#> 4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1             TRUE
#> 5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2             TRUE
#> 6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1             TRUE

# How would I make the command equivalent to if I wrote
mtcars[, `:=` (xMPGBiggerThan20 = mpg > 20)]

# Desired result
head(mtcars)
#>     mpg cyl disp  hp drat    wt  qsec vs am gear carb xMPGBiggerThan20
#> 1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4             TRUE
#> 2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4             TRUE
#> 3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1             TRUE
#> 4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1             TRUE
#> 5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2            FALSE
#> 6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1            FALSE

Created on 2022-02-14 by the reprex package (v2.0.1)

Body:
You can try  (data.table 1.14.3)

mtcars[, xMPGBiggerThan20 := colname > 20, env = list(colname = "mpg")][]

or

mtcars[, `:=` (xMPGBiggerThan20 = colname > 20), env = list(colname = "mpg")][]

If you don't want to update to the development version, you can consider to use

mtcars[, `:=` (xMPGBiggerThan20 = get(colname) > 20)]

PS: You can update to the newest version with data.table::update.dev.pkg()

Ref: https://rdatatable.gitlab.io/data.table/articles/datatable-programming.html


问:
Implementation of Bag using only a Java Array
I have pretty much the whole Bag class implemented correctly and it has been proven to work, except for this remove method. The overall time complexity should be O(length). I'm trying to accomplish this by moving the element to be removed to the end of the array and swapping it with the last element. Then, I use Arrays.copyOf() to truncate the array.

```<code>public void remove(String s)
    {
        for (int i = 0; i < length; i++) {
            if(bag[i].equals(s)){

                // Adding bag[i] to end of array:
                if (length == SIZE){
                    SIZE *= 2;
                    bag = Arrays.copyOf(bag, SIZE);
                }
                bag[length] = bag[i];

                // Moving last element to bag[i]:
                bag[i] = bag[length-1];

                bag = Arrays.copyOf(bag, length-1);
                length--;
            }
        }
    }
</code>```

If you look at my output, the removal is successful with the removal of 'Cucumber', but when I go to remove the first element in the list, 'Cabbage', it results in an index out of bounds error.

Output:

```<code>ADD Guava
Bag: {Cabbage, Cucumber, Broccoli, Banana, Broccoli, Guava}

REMOVE Cucumber
Bag: {Cabbage, Guava, Broccoli, Banana, Broccoli}

REMOVE Cucumber
Bag: {Cabbage, Guava, Broccoli, Banana, Broccoli}

REMOVE Cabbage
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at ArrayBag.remove(ArrayBag.java:84)
    at Main.<init>(Main.java:53)
    at Main.main(Main.java:15)

Process finished with exit code 1

</code>```

I would really appreciate any help in understanding why I'm getting this error. Thank you!

答:
A bag is an unordered collection of things.  The quickest way to remove an item in the bag is to replace it with the last item in the array and decrementing the count.  Below is how you would remove an item.  I remove the void add(String item) and String toString() method, only showing just the remove method.  O(n) because of the linear search for the item in the array.

```<code>class Bag {
   private String[] items = new String[100];
   private int size = 0;

   void remove(String item){
      int index = indexOf(item);
      if (index >= 0)
        items[index] = items[--size];
   }
   private int indexOf(String item){
      for(int i=0; i<size; i++)
        if (items[i].equals(item))
          return i;
      return -1;
   }
}
</code>```

Example usage:

```<code>public class Main{
    public static void main(String[] args) {
        Bag b = new Bag();
        b.add("apple");
        b.add("banana");
        b.add("orange");
        System.out.println(b);
        b.remove("banana");
        System.out.println(b);
        b.remove("apple");
        System.out.println(b);
    }
}
</code>```

Output

```<code>Bag [apple, banana, orange]
Bag [apple, orange]
Bag [orange]
</code>```

Body:
I have pretty much the whole Bag class implemented correctly and it has been proven to work, except for this remove method. The overall time complexity should be O(length). I'm trying to accomplish this by moving the element to be removed to the end of the array and swapping it with the last element. Then, I use Arrays.copyOf() to truncate the array.

public void remove(String s)
    {
        for (int i = 0; i < length; i++) {
            if(bag[i].equals(s)){

                // Adding bag[i] to end of array:
                if (length == SIZE){
                    SIZE *= 2;
                    bag = Arrays.copyOf(bag, SIZE);
                }
                bag[length] = bag[i];

                // Moving last element to bag[i]:
                bag[i] = bag[length-1];

                bag = Arrays.copyOf(bag, length-1);
                length--;
            }
        }
    }

If you look at my output, the removal is successful with the removal of 'Cucumber', but when I go to remove the first element in the list, 'Cabbage', it results in an index out of bounds error.

Output:

ADD Guava
Bag: {Cabbage, Cucumber, Broccoli, Banana, Broccoli, Guava}

REMOVE Cucumber
Bag: {Cabbage, Guava, Broccoli, Banana, Broccoli}

REMOVE Cucumber
Bag: {Cabbage, Guava, Broccoli, Banana, Broccoli}

REMOVE Cabbage
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
    at ArrayBag.remove(ArrayBag.java:84)
    at Main.<init>(Main.java:53)
    at Main.main(Main.java:15)

Process finished with exit code 1

I would really appreciate any help in understanding why I'm getting this error. Thank you!

Body:
A bag is an unordered collection of things.  The quickest way to remove an item in the bag is to replace it with the last item in the array and decrementing the count.  Below is how you would remove an item.  I remove the void add(String item) and String toString() method, only showing just the remove method.  O(n) because of the linear search for the item in the array.

class Bag {
   private String[] items = new String[100];
   private int size = 0;

   void remove(String item){
      int index = indexOf(item);
      if (index >= 0)
        items[index] = items[--size];
   }
   private int indexOf(String item){
      for(int i=0; i<size; i++)
        if (items[i].equals(item))
          return i;
      return -1;
   }
}

Example usage:

public class Main{
    public static void main(String[] args) {
        Bag b = new Bag();
        b.add("apple");
        b.add("banana");
        b.add("orange");
        System.out.println(b);
        b.remove("banana");
        System.out.println(b);
        b.remove("apple");
        System.out.println(b);
    }
}

Output

Bag [apple, banana, orange]
Bag [apple, orange]
Bag [orange]


问:
What is the difference between a table variable and a local temporary table in OpenGauss?
What is the difference between a table variable and a local temporary table in OpenGauss?</p>

答:
A local temporary table is automatically dropped at the end of the current session. Therefore, you can create and use temporary tables in the current session as long as the connected database node in the session is normal. Temporary tables are created only in the current session. If a DDL statement involves operations on temporary tables, a DDL error will be generated. Therefore, you are not advised to perform operations on temporary tables in DDL statements.
You can refer to this link for more detailed information.
https://opengauss.org/en/docs/latest/docs/Developerguide/create-table.html</p>


问:
SQL Server XML Query Advice
I'm writing a user-defined function to extract values from an XML column in SQL Server which represents a simple dictionary of string key-value pairs.  The only way I've made it work so far seems overly complex.  Do you have any simplifying suggestions or tips for the DictValue function below?

```<code>IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DictValue]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[DictValue]
go

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TableWithXmlColumn]') AND type in (N'U'))
DROP TABLE [dbo].[TableWithXmlColumn]
go

create table TableWithXmlColumn (
    Id int identity primary key
    ,Dict xml
    )
go

create function DictValue(
    @id int
    ,@key nvarchar(max)
    ) returns nvarchar(max) as begin

    declare @d xml -- string Dictionary
    select @d = Dict from TableWithXmlColumn where Id = @id
    declare @value xml
    select
            @value = d.Pair.value('data(.)', 'nvarchar(max)')
        from
            @d.nodes('/StringDictionary/Pair') as d(Pair)
        where
            @key = d.Pair.value('./@Key', 'nvarchar(max)')

    return convert(nvarchar(max), @value)
    end
go

declare @xmlId int
insert TableWithXmlColumn (Dict) values (
    N'<?xml version="1.0" encoding="utf-16"?>
    <StringDictionary>
      <Pair Key="color">red</Pair>
      <Pair Key="count">123</Pair>
    </StringDictionary>')
set @xmlId = scope_identity()

select
    dbo.DictValue(@xmlId, 'color') as color
    ,dbo.DictValue(@xmlId, 'count') as [count]
</code>```

答:
Personally I don't see much that you can do, the code that you have is structured in a way that is very readable, and you are querying the XML to get the result set first, then grabbing the values.

You might be able to get around the use of the @d variable, however, I believe the readability of the code will suffer greatly.

OwnerDisplayName: ESV

ContentLicense: CC BY-SA 2.5

Title: SQL Server XML Query Advice

Body:
I'm writing a user-defined function to extract values from an XML column in SQL Server which represents a simple dictionary of string key-value pairs.  The only way I've made it work so far seems overly complex.  Do you have any simplifying suggestions or tips for the DictValue function below?

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[DictValue]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[DictValue]
go

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TableWithXmlColumn]') AND type in (N'U'))
DROP TABLE [dbo].[TableWithXmlColumn]
go

create table TableWithXmlColumn (
    Id int identity primary key
    ,Dict xml
    )
go

create function DictValue(
    @id int
    ,@key nvarchar(max)
    ) returns nvarchar(max) as begin

    declare @d xml -- string Dictionary
    select @d = Dict from TableWithXmlColumn where Id = @id
    declare @value xml
    select
            @value = d.Pair.value('data(.)', 'nvarchar(max)')
        from
            @d.nodes('/StringDictionary/Pair') as d(Pair)
        where
            @key = d.Pair.value('./@Key', 'nvarchar(max)')

    return convert(nvarchar(max), @value)
    end
go

declare @xmlId int
insert TableWithXmlColumn (Dict) values (
    N'<?xml version="1.0" encoding="utf-16"?>
    <StringDictionary>
      <Pair Key="color">red</Pair>
      <Pair Key="count">123</Pair>
    </StringDictionary>')
set @xmlId = scope_identity()

select
    dbo.DictValue(@xmlId, 'color') as color
    ,dbo.DictValue(@xmlId, 'count') as [count]

OwnerDisplayName: Mitchel Sellers


问:
JT file format : Building huffman tree
I am trying to read a JT File.
JT file may have information which is compressed by using Huffman Algorithm.
I am facing a problem while building the Huffman tree.
There's an ambiguity in the implementation which occurs when two symbols have the same frequency, depending on the comparison that we use between the nodes, the order may be different and leads to an inversion of some branches of the tree.
So I am unable to build proper Huffman tree.
Have anyone faced this issue earlier?
Is there any solution for this?</p>

答:
I have faced the same issue when I tried to implement a parser for JT. Didn't get a solution.
I also tried to contact some guys from Siemens but without getting a solution. There IS an ambiguity which can't be solved without further information from Siemens. The Spec alone doesn't help.
But I think Huffman is dropped out in the newest JT Spec.</p>

Title: JT file format : Building huffman tree