问:
NestJS + CASL + Mongoose: CASL cannot infer subject type from Mongoose Schema

Context

I have defined a Cat schema using Mongoose and NestJS:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;

@Schema()
export class Cat {
  @Prop({ required: true })
  name: string;

  @Prop({ required: true })
  breed: string;

  @Prop({ required: true })
  createdBy: string;

  // Other fields...
}

export const CatSchema = SchemaFactory.createForClass(Cat);
```
<p>I have also defined an ability factory using CASL to handle authorization for my API:</p>
<pre class="lang-js prettyprint-override"><code>import {
  Ability,
  AbilityBuilder,
  AbilityClass,
  ExtractSubjectType,
  InferSubjects,
} from '@casl/ability';
import { Injectable } from '@nestjs/common';
import { Cat } from '../cats/schemas/cat.schema';
import { User } from '../users/models/user.model';

type Subjects = InferSubjects<typeof Cat | typeof User> | 'all';

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    can(Action.Read, Cat);
    can(Action.Create, Cat);
    can(Action.Update, Cat, {
      createdBy: user.id,
    });

    if (user.isAdmin()) {
      can(Action.Manage, 'all');
    }

    return build({
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}

</code>```

Problem

When I try to check permissions in my service (note: the user is not an administrator):

import {
  ForbiddenException,
  Injectable,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { EditCatInput } from './dto/edit-cat.input';
import { Cat, CatDocument } from './schemas/cat.schema';
import { Action, CaslAbilityFactory } from '../casl/casl-ability.factory';
import { User } from '../users/models/user.model';

@Injectable()
export class CatsService {
  constructor(
    private readonly configService: ConfigService,
    private readonly caslAbilityFactory: CaslAbilityFactory,
    @InjectModel(Cat.name) private catModel: Model<CatDocument>,
  ) {}

  // Other methods...

  async update(id: string, input: EditCatInput, user: User): Promise<Cat> {
    const updatedCat = await this.catModel
      .findOne({
        _id: { $eq: id },
        deleted: { $eq: false },
      })
      .exec();
    const ability = this.caslAbilityFactory.createForUser(user);
    if (!ability.can(Action.Update, updatedCat)) {
      throw new ForbiddenException(
        'You cannot edit this cat.',
      );
    }
    Object.assign(updatedCat, input);
    await updatedCat.save();

    return updatedCat;
  }
}
```

ability.can(Action.Update, cat) always return false, while it should be true.

Additional information

ability.can returns false for any action when the user is not administrator.

My guess is that CASL cannot infer the subject type of my Mongoose model using the Cat class in InferSubject interface of the ability builder. But I don't know which class to use to infer subject type correctly.

What did I miss?

答:
So the key is to inject the cat model over nest js injection in the casl ability factory.
So a factory like this should work:

import {
    Ability,
    AbilityBuilder,
    AbilityClass,
    ExtractSubjectType,
    InferSubjects,
  } from '@casl/ability';
  import { Injectable } from '@nestjs/common';
  import { InjectModel } from '@nestjs/mongoose';
  import { Model } from 'mongoose';
  import { Cat, CatDocument } from '../cats/schemas/cat.schema';
  import { User } from '../users/models/user.model';

  export enum Action {
    Manage = 'manage',
    Create = 'create',
    Read = 'read',
    Update = 'update',
    Delete = 'delete',
  }

  @Injectable()
  export class CaslAbilityFactory {
    constructor(
        @InjectModel(Cat.name)
        private catModel: Model<CatDocument>,
    ) {}
    createForUser(user: User) {
      const { can, build } = new AbilityBuilder(
        Ability as AbilityClass<
          Ability<[Action, InferSubjects<typeof this.catModel> | 'all']>
        >,
      );

      can(Action.Read, this.catModel);
      can(Action.Create, this.catModel);
      can(Action.Update, this.catModel, {
        createdBy: user.id,
      });

      if (user.isAdmin()) {
        can(Action.Manage, 'all');
      }

      return build({
        detectSubjectType: (item) =>
          item.constructor as ExtractSubjectType<InferSubjects<typeof this.catModel> | 'all'>,
      });
    }
  }
```

full example project:
https://github.com/Wenish/nestjs-mongoose-casl

Body:
Context

I have defined a Cat schema using Mongoose and NestJS:

import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';

export type CatDocument = Cat & Document;

@Schema()
export class Cat {
  @Prop({ required: true })
  name: string;

  @Prop({ required: true })
  breed: string;

  @Prop({ required: true })
  createdBy: string;

  // Other fields...
}

export const CatSchema = SchemaFactory.createForClass(Cat);

I have also defined an ability factory using CASL to handle authorization for my API:

import {
  Ability,
  AbilityBuilder,
  AbilityClass,
  ExtractSubjectType,
  InferSubjects,
} from '@casl/ability';
import { Injectable } from '@nestjs/common';
import { Cat } from '../cats/schemas/cat.schema';
import { User } from '../users/models/user.model';

type Subjects = InferSubjects<typeof Cat | typeof User> | 'all';

export enum Action {
  Manage = 'manage',
  Create = 'create',
  Read = 'read',
  Update = 'update',
  Delete = 'delete',
}

export type AppAbility = Ability<[Action, Subjects]>;

@Injectable()
export class CaslAbilityFactory {
  createForUser(user: User) {
    const { can, build } = new AbilityBuilder<
      Ability<[Action, Subjects]>
    >(Ability as AbilityClass<AppAbility>);

    can(Action.Read, Cat);
    can(Action.Create, Cat);
    can(Action.Update, Cat, {
      createdBy: user.id,
    });

    if (user.isAdmin()) {
      can(Action.Manage, 'all');
    }

    return build({
      detectSubjectType: (item) =>
        item.constructor as ExtractSubjectType<Subjects>,
    });
  }
}

Problem

When I try to check permissions in my service (note: the user is not an administrator):

import {
  ForbiddenException,
  Injectable,
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { EditCatInput } from './dto/edit-cat.input';
import { Cat, CatDocument } from './schemas/cat.schema';
import { Action, CaslAbilityFactory } from '../casl/casl-ability.factory';
import { User } from '../users/models/user.model';

@Injectable()
export class CatsService {
  constructor(
    private readonly configService: ConfigService,
    private readonly caslAbilityFactory: CaslAbilityFactory,
    @InjectModel(Cat.name) private catModel: Model<CatDocument>,
  ) {}

  // Other methods...

  async update(id: string, input: EditCatInput, user: User): Promise<Cat> {
    const updatedCat = await this.catModel
      .findOne({
        _id: { $eq: id },
        deleted: { $eq: false },
      })
      .exec();
    const ability = this.caslAbilityFactory.createForUser(user);
    if (!ability.can(Action.Update, updatedCat)) {
      throw new ForbiddenException(
        'You cannot edit this cat.',
      );
    }
    Object.assign(updatedCat, input);
    await updatedCat.save();

    return updatedCat;
  }
}

ability.can(Action.Update, cat) always return false, while it should be true.

Additional information

ability.can returns false for any action when the user is not administrator.

My guess is that CASL cannot infer the subject type of my Mongoose model using the Cat class in InferSubject interface of the ability builder. But I don't know which class to use to infer subject type correctly.

What did I miss?

Body:
So the key is to inject the cat model over nest js injection in the casl ability factory.
So a factory like this should work:

import {
    Ability,
    AbilityBuilder,
    AbilityClass,
    ExtractSubjectType,
    InferSubjects,
  } from '@casl/ability';
  import { Injectable } from '@nestjs/common';
  import { InjectModel } from '@nestjs/mongoose';
  import { Model } from 'mongoose';
  import { Cat, CatDocument } from '../cats/schemas/cat.schema';
  import { User } from '../users/models/user.model';

  export enum Action {
    Manage = 'manage',
    Create = 'create',
    Read = 'read',
    Update = 'update',
    Delete = 'delete',
  }

  @Injectable()
  export class CaslAbilityFactory {
    constructor(
        @InjectModel(Cat.name)
        private catModel: Model<CatDocument>,
    ) {}
    createForUser(user: User) {
      const { can, build } = new AbilityBuilder(
        Ability as AbilityClass<
          Ability<[Action, InferSubjects<typeof this.catModel> | 'all']>
        >,
      );

      can(Action.Read, this.catModel);
      can(Action.Create, this.catModel);
      can(Action.Update, this.catModel, {
        createdBy: user.id,
      });

      if (user.isAdmin()) {
        can(Action.Manage, 'all');
      }

      return build({
        detectSubjectType: (item) =>
          item.constructor as ExtractSubjectType<InferSubjects<typeof this.catModel> | 'all'>,
      });
    }
  }

full example project:
https://github.com/Wenish/nestjs-mongoose-casl


来源: stackexchange

问:
What's correct path to html pages for loading into WebView?
I know that there are a lot of questions about to load HTMl-pages into WebView.
What am I doing? I just put down the 1.html in assets folder in android-project and use

```<code>myWebView.loadUrl("file:///assets/"+selectedItem+".html");
</code>```

where
    selecteditem

is data from intent. As result I get the message in WebView that:

file:///assets/1.html  was not found.

UPD: sorry, I found the solution. the correct path should be the follow:

```<code>myWebView.loadUrl("file:///android_asset/"+selectedItem+".html");
</code>```

答: The correct path is file:///android_asset/1.html

ContentLicense: CC BY-SA 3.0

Body:
I know that there are a lot of questions about to load HTMl-pages into WebView.
What am I doing? I just put down the 1.html in assets folder in android-project and use

myWebView.loadUrl("file:///assets/"+selectedItem+".html");

where
    selecteditem

is data from intent. As result I get the message in WebView that:

file:///assets/1.html  was not found.

UPD: sorry, I found the solution. the correct path should be the follow:

myWebView.loadUrl("file:///android_asset/"+selectedItem+".html");


问:
How do I stop a currently running jenkins build if a new build is triggered with same parameters?
I have a declarative pipeline in Jenkins which builds and pushes docker images to two different container registries. I have configured another freestyle job to lookout for any changes in a few branches and passes the branch name as parameter to declarative pipeline (Branch name is the only parameter for now).

Now, I want to abort the running build, if there's a new build triggered with the same Branch name (or same parameters). How can I do this in a declarative pipeline?

Thanks in advance.

答:
You may want to check:

https://stackoverflow.com/a/59195377/2047614

In your case need to compare parameters as well, see Finding previous Jenkins job that had a specific param value, but without using `hudson.model.Hudson`

ContentLicense: CC BY-SA 4.0


问:
FormulaR1C1 not running across a selected range
I'm trying to make a macro where I can find a set of products and get an average weekly sales figure. However, FormulaR1C1 is only applying to the first figure in a selection and not all active cells. Any help as to why it doesn't apply for the whole range?</p>
```<code>
Option Compare Text
Private Sub submit_Click()

Dim emptyRow As Long
Dim Rng As Range
Dim myCell As Object
Dim mySelection As Range

Range("R1:S1").Select
Range("R1:S1").Clear
ActiveCell.FormulaR1C1 = ""

emptyRow = WorksheetFunction.CountA(Range("R:R")) + 1

Cells(emptyRow, 18).Value = search.Value
Cells(emptyRow, 19).Value = week.Value

 Set Rng = Range("A1:A2000")
 searchString = Range("R1")
 For Each myCell In Rng
 If InStr(myCell.Text, searchString) Then
      If Not mySelection Is Nothing Then
          Set mySelection = Union(mySelection, myCell)
      Else
          Set mySelection = myCell
      End If
 End If
 Next
 If mySelection Is Nothing Then
     MsgBox "The product was not found in the selection"
 Else
     mySelection.Offset(0, 4).Select
 End If

    ActiveCell.FormulaR1C1 = "=RC[-2] /" & Range("S1")

Unload Me

End Sub
</code>```

答:
The selection may contain more than one cell, but only one is the active cell.

    If mySelection Is Nothing Then
         MsgBox "The product was not found in the selection"
    Else
         mySelection.Offset(, 4).FormulaR1C1 = "=RC[-2] /" & Range("S1")
    End If

```

Body:
I'm trying to make a macro where I can find a set of products and get an average weekly sales figure. However, FormulaR1C1 is only applying to the first figure in a selection and not all active cells. Any help as to why it doesn't apply for the whole range?

Option Compare Text
Private Sub submit_Click()

Dim emptyRow As Long
Dim Rng As Range
Dim myCell As Object
Dim mySelection As Range

Range("R1:S1").Select
Range("R1:S1").Clear
ActiveCell.FormulaR1C1 = ""

emptyRow = WorksheetFunction.CountA(Range("R:R")) + 1

Cells(emptyRow, 18).Value = search.Value
Cells(emptyRow, 19).Value = week.Value

 Set Rng = Range("A1:A2000")
 searchString = Range("R1")
 For Each myCell In Rng
 If InStr(myCell.Text, searchString) Then
      If Not mySelection Is Nothing Then
          Set mySelection = Union(mySelection, myCell)
      Else
          Set mySelection = myCell
      End If
 End If
 Next
 If mySelection Is Nothing Then
     MsgBox "The product was not found in the selection"
 Else
     mySelection.Offset(0, 4).Select
 End If

    ActiveCell.FormulaR1C1 = "=RC[-2] /" & Range("S1")

Unload Me

End Sub


问:
flutter "Could not find the correct Provider<UserProvider> above this PickupLayout Widget"
I get the error "Could not find the correct Provider above this PickupLayout Widget" when I use navigation.push over a showDialog query. Whithout the showDialog popup it works

```<code>...
Padding(
    padding: const EdgeInsets.only(right: 15),
    child: IconButton(
    icon:Icon(Icons.check),
        nPressed: () {
            query_popup();   // using navigator.push at this position works
           },
          ),
        ),

...

query_popup() {
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(8.0),
            ),
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Container(height: 5.0),
              Text("End & save?"),
              Container(height: 20.0),
              InkWell(                        // using navigator.push at this posistion doesn't work
                onTap: () {
                  Navigator.push(context,MaterialPageRoute(builder: (context) => TabbarScreen(SelectedPage: 0)),);
                },
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(width: 10.0, height: 40.0),
                    Text('Yes'),
                  ],
                ),
              ),
              Container(height: 5.0),
              InkWell(
                onTap: () {
                  Navigator.pop(context);
                },
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(width: 20.0, height: 40.0),
                    Text('No')
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}
</code>```

Full error description:
Error: Could not find the correct Provider above this PickupLayout Widget
This likely happens because you used a BuildContext that does not include the provider
of your choice. There are a few common scenarios:

The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.

You used a BuildContext that is an ancestor of the provider you are trying to read.
Make sure that PickupLayout is under your MultiProvider/Provider.
This usually happen when you are creating a provider and trying to read it immediately.

答: wrap TabbarScreen with Provider worked, thx @ikerfah</p>

Body:
I get the error "Could not find the correct Provider above this PickupLayout Widget" when I use navigation.push over a showDialog query. Whithout the showDialog popup it works

...
Padding(
    padding: const EdgeInsets.only(right: 15),
    child: IconButton(
    icon:Icon(Icons.check),
        nPressed: () {
            query_popup();   // using navigator.push at this position works
           },
          ),
        ),

...

query_popup() {
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(
              Radius.circular(8.0),
            ),
          ),
          content: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Container(height: 5.0),
              Text("End & save?"),
              Container(height: 20.0),
              InkWell(                        // using navigator.push at this posistion doesn't work
                onTap: () {
                  Navigator.push(context,MaterialPageRoute(builder: (context) => TabbarScreen(SelectedPage: 0)),);
                },
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(width: 10.0, height: 40.0),
                    Text('Yes'),
                  ],
                ),
              ),
              Container(height: 5.0),
              InkWell(
                onTap: () {
                  Navigator.pop(context);
                },
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Container(width: 20.0, height: 40.0),
                    Text('No')
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

Full error description:
Error: Could not find the correct Provider above this PickupLayout Widget
This likely happens because you used a BuildContext that does not include the provider
of your choice. There are a few common scenarios:

The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.

You used a BuildContext that is an ancestor of the provider you are trying to read.
Make sure that PickupLayout is under your MultiProvider/Provider.
This usually happen when you are creating a provider and trying to read it immediately.


问:
How to upload an image from a remote website, by using javascript?
Is there any way I can do that? For example, I have an

```<code><input type="file" id="upload_file" />
</code>```

Obviously I can't just

```<code>$('#upload_file').val('http://www.site.com/path/to/image.jpg').parent().submit();
</code>```

答:
You can't do it.

Javascript won't let you read from other domains (for security reasons).

File inputs don't accept URL inputs (or for that matter paths) AFAIK.

Body:
Is there any way I can do that? For example, I have an

<input type="file" id="upload_file" />

Obviously I can't just

$('#upload_file').val('http://www.site.com/path/to/image.jpg').parent().submit();


问:
Prometheus: find max RPS
Say I have two metrics in Prometheus, both counters:

Ok:

```<code>nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status="200"}
</code>```

Failure:

```<code>nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}
</code>```

Total:

```<code>nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}
</code>```

My question is how to find on which RPS failures occurred as promQL query

I'm expecting the following response:

```<code>400
</code>```

Means, that if pod receives > 400 RPS, Failure metric begin to happen

full query (after got answered)

```<code>sum((sum(rate(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}[$__rate_interval])) without (status))
  and
  (sum(rate(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status !="200"}[$__rate_interval])) without (status) > 0))
</code>```

答:
You need the following query:

```<code>rps_total and (rps_failure > 0)
</code>```

The and binary operation is used for matching right-hand time series to the left-hand series with the same set of labels. See these docs for details on matching rules.

Let's substitute rps_total and rps_failure with the actual time series given matching rules mentioned above.

The rps_total is substituted with sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}) without (status) . The sum(...) without (status) is needed in order to sum metrics across all the status labels grouped by the remaining labels.

The rps_failure is substituted with sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}) without (status)

Then the final PromQL query will look like:

```<code>(
  sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}) without (status)
  and
  (sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}) without (status) > 0)
)
</code>```

Title: Prometheus: find max RPS

Body:
Say I have two metrics in Prometheus, both counters:

Ok:

nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status="200"}

Failure:

nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}

Total:

nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}

My question is how to find on which RPS failures occurred as promQL query

I'm expecting the following response:

400

Means, that if pod receives > 400 RPS, Failure metric begin to happen

full query (after got answered)

sum((sum(rate(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}[$__rate_interval])) without (status))
  and
  (sum(rate(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status !="200"}[$__rate_interval])) without (status) > 0))

Body:
You need the following query:

rps_total and (rps_failure > 0)

The and binary operation is used for matching right-hand time series to the left-hand series with the same set of labels. See these docs for details on matching rules.

Let's substitute rps_total and rps_failure with the actual time series given matching rules mentioned above.

The rps_total is substituted with sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}) without (status) . The sum(...) without (status) is needed in order to sum metrics across all the status labels grouped by the remaining labels.

The rps_failure is substituted with sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}) without (status)

Then the final PromQL query will look like:

(
  sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service"}) without (status)
  and
  (sum(nginx_ingress_controller_requests{prometheus_from="$cluster", ingress="brand-safety-phoenix-service", status!="200"}) without (status) > 0)
)


问:
Loop through Python dictionary and add different values with same keys to a new dictionary
I am really stuck with this exercise. How can I with a for loop add the same keys with a new values to a different dictionary in Python?

Goal is to loops through student grades and replace them with "Excellent", "Bad", etc.

This is as far as I could get:

student_scores = {
  "Harry": 81,
  "Ron": 78,
  "Hermione": 99,
  "Draco": 74,
  "Neville": 62,
}

student_grades = {}

for key, value in student_scores.items():
    print(key, value)

print(student_grades)
```

Much appreciated in advance!

答:
You can add values to a dictionary by simply assigning the value to the dictionary indexed by the key. For example, student_grades["Harry"] = "Excellent"

You can do the same in your loop:

```<code>for key, value in student_scores.items():
    student_grades[key] = "Excellent"
</code>```

if course, you'll not assign the same value (grade) for all keys. Use an if statement or any other conditional logic to select which grade to assign to each student. For example:

```<code>for key, value in student_scores.items():
    if (value > 90)
        student_grades[key] = "Excellent"
    else
        student_grades[key] = "Okey-ish"
</code>```

Body:
I am really stuck with this exercise. How can I with a for loop add the same keys with a new values to a different dictionary in Python?

Goal is to loops through student grades and replace them with "Excellent", "Bad", etc.

This is as far as I could get:

student_scores = {
  "Harry": 81,
  "Ron": 78,
  "Hermione": 99,
  "Draco": 74,
  "Neville": 62,
}

student_grades = {}

for key, value in student_scores.items():
    print(key, value)

print(student_grades)

Much appreciated in advance!

Body:
You can add values to a dictionary by simply assigning the value to the dictionary indexed by the key. For example, student_grades["Harry"] = "Excellent"

You can do the same in your loop:

for key, value in student_scores.items():
    student_grades[key] = "Excellent"

if course, you'll not assign the same value (grade) for all keys. Use an if statement or any other conditional logic to select which grade to assign to each student. For example:

for key, value in student_scores.items():
    if (value > 90)
        student_grades[key] = "Excellent"
    else
        student_grades[key] = "Okey-ish"


问:
Can I make multiple assignments within a given case_when true clause?
Update: Apparently this feature is now planned for dplyr, as discussed here: https://github.com/tidyverse/dplyr/pull/6145

In SQL one can assign multiple variables - say var1 and var2 - when a given case is verified, with a construction like

case when condition then var1 = x, var2 = y

Does dplyr::case_when (or anything else in the tidyverse) support this useful feature), and if so, how?!

Note that in the example below, var1, var2  and var3 have exactly the same test conditions, i.e. Species == "setosa", and the degenerate case TRUE. I want to reduce this redundancy by not repeating the conditions: one call to case_when (or similar), albeit with different eval_on_true expressions for var1, var2 and var3, respectively. Obviously redundancy is not a problem here in this example, but my case_when's get very large and complex in real life examples.

library(tidyverse)

# create example data
set.seed(1337)
data <- iris %>%
  sample_n(5) %>%
  select(Petal.Length, Petal.Width, Species) %>%
  as_tibble()
data
#> # A tibble: 5 × 3
#>   Petal.Length Petal.Width Species
#>          <dbl>       <dbl> <fct>
#> 1          5.5         1.8 virginica
#> 2          5           1.9 virginica
#> 3          1.5         0.2 setosa
#> 4          5.9         2.3 virginica
#> 5          4.1         1.3 versicolor
data %>%
  mutate(var1 = case_when(Species == "setosa" ~ "green", TRUE ~ "blue"),
         var2 = case_when(Species == "setosa" ~ Petal.Length * 99, TRUE ~ Petal.Length),
         var3 = case_when(Species == "setosa" ~ as.Date("2002-12-01"), TRUE ~ as.Date("2003-12-02")))
#> # A tibble: 5 × 6
#>   Petal.Length Petal.Width Species    var1   var2 var3
#>          <dbl>       <dbl> <fct>      <chr> <dbl> <date>
#> 1          5.5         1.8 virginica  blue    5.5 2003-12-02
#> 2          5           1.9 virginica  blue    5   2003-12-02
#> 3          1.5         0.2 setosa     green 148.  2002-12-01
#> 4          5.9         2.3 virginica  blue    5.9 2003-12-02
#> 5          4.1         1.3 versicolor blue    4.1 2003-12-02
```

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

答:
If we want to create new columns by multiplying a single column with different values, one tidyverse approach is to use imap (by default the default .y is the sequence if we pass unnamed elements) to loop over the multiplier values, return a single column with transmute and then bind those columns with the original data

```<code>library(purrr)
library(dplyr)
library(stringr)
imap_dfc(c(10, 99), ~ data %>%
   transmute(!! str_c('var', .y) :=
   case_when(Species == "setosa"~ Petal.Length * .x,
              TRUE ~ Petal.Length))) %>%
   bind_cols(data, .)
</code>```

-output

```<code># A tibble: 5 × 7
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species     var1  var2
         <dbl>       <dbl>        <dbl>       <dbl> <fct>      <dbl> <dbl>
1          6.4         3.1          5.5         1.8 virginica    5.5   5.5
2          6.3         2.5          5           1.9 virginica    5     5
3          5.3         3.7          1.5         0.2 setosa      15   148.
4          6.8         3.2          5.9         2.3 virginica    5.9   5.9
5          5.7         2.8          4.1         1.3 versicolor   4.1   4.1
</code>```

Body:
Update: Apparently this feature is now planned for dplyr, as discussed here: https://github.com/tidyverse/dplyr/pull/6145

In SQL one can assign multiple variables - say var1 and var2 - when a given case is verified, with a construction like

case when condition then var1 = x, var2 = y

Does dplyr::case_when (or anything else in the tidyverse) support this useful feature), and if so, how?!

Note that in the example below, var1, var2  and var3 have exactly the same test conditions, i.e. Species == "setosa", and the degenerate case TRUE. I want to reduce this redundancy by not repeating the conditions: one call to case_when (or similar), albeit with different eval_on_true expressions for var1, var2 and var3, respectively. Obviously redundancy is not a problem here in this example, but my case_when's get very large and complex in real life examples.

library(tidyverse)

# create example data
set.seed(1337)
data <- iris %>%
  sample_n(5) %>%
  select(Petal.Length, Petal.Width, Species) %>%
  as_tibble()
data
#> # A tibble: 5 × 3
#>   Petal.Length Petal.Width Species
#>          <dbl>       <dbl> <fct>
#> 1          5.5         1.8 virginica
#> 2          5           1.9 virginica
#> 3          1.5         0.2 setosa
#> 4          5.9         2.3 virginica
#> 5          4.1         1.3 versicolor
data %>%
  mutate(var1 = case_when(Species == "setosa" ~ "green", TRUE ~ "blue"),
         var2 = case_when(Species == "setosa" ~ Petal.Length * 99, TRUE ~ Petal.Length),
         var3 = case_when(Species == "setosa" ~ as.Date("2002-12-01"), TRUE ~ as.Date("2003-12-02")))
#> # A tibble: 5 × 6
#>   Petal.Length Petal.Width Species    var1   var2 var3
#>          <dbl>       <dbl> <fct>      <chr> <dbl> <date>
#> 1          5.5         1.8 virginica  blue    5.5 2003-12-02
#> 2          5           1.9 virginica  blue    5   2003-12-02
#> 3          1.5         0.2 setosa     green 148.  2002-12-01
#> 4          5.9         2.3 virginica  blue    5.9 2003-12-02
#> 5          4.1         1.3 versicolor blue    4.1 2003-12-02

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

Body:
If we want to create new columns by multiplying a single column with different values, one tidyverse approach is to use imap (by default the default .y is the sequence if we pass unnamed elements) to loop over the multiplier values, return a single column with transmute and then bind those columns with the original data

library(purrr)
library(dplyr)
library(stringr)
imap_dfc(c(10, 99), ~ data %>%
   transmute(!! str_c('var', .y) :=
   case_when(Species == "setosa"~ Petal.Length * .x,
              TRUE ~ Petal.Length))) %>%
   bind_cols(data, .)

-output

# A tibble: 5 × 7
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species     var1  var2
         <dbl>       <dbl>        <dbl>       <dbl> <fct>      <dbl> <dbl>
1          6.4         3.1          5.5         1.8 virginica    5.5   5.5
2          6.3         2.5          5           1.9 virginica    5     5
3          5.3         3.7          1.5         0.2 setosa      15   148.
4          6.8         3.2          5.9         2.3 virginica    5.9   5.9
5          5.7         2.8          4.1         1.3 versicolor   4.1   4.1


问:
Selecting first non null value in a model
Let's say I have a model class that looks like this:

```<code>   public class ModelTest {
        public string val1 {get;set;}
        public string val2 {get;set;}
        public string val3 {get;set;}
   }
</code>```

Somewhere in my code this ModelTest gets its data. The caveat is that, only 1 of them will hold a value

```<code>   var model = new ModelTest() {val1=null, val2="value", val3=null} //Sudo code
</code>```

What I am trying to do somehow, is compare a value to whichever 1 of the 3 items can potentially have a values, so something like:

```<code>     var testCompare = "someValue"

     if (testCompare == model. ....//how can I get the NOT NULL value from ModelTest here for comparison
</code>```

答:
What about solution which contains combination of reflection and Linq,

Test Data

```<code>var model = new ModelTest() {val1=null, val2="value", val3=null} ;
</code>```

Usage

```<code>var result =
    model.GetType()
    .GetProperties()
    .FirstOrDefault(prop => prop.GetValue(model, null) != null);
</code>```

Print result

```<code>Console.WriteLine(result.GetValue(model));
</code>```

This is my first attempt with reflection, suggestions are most welcome

.Net fiddle

Note: This is just an alternate solution, less performant. If you are looking for elegant solution, then kindly try other solutions.

Body:
Let's say I have a model class that looks like this:

   public class ModelTest {
        public string val1 {get;set;}
        public string val2 {get;set;}
        public string val3 {get;set;}
   }

Somewhere in my code this ModelTest gets its data. The caveat is that, only 1 of them will hold a value

   var model = new ModelTest() {val1=null, val2="value", val3=null} //Sudo code

What I am trying to do somehow, is compare a value to whichever 1 of the 3 items can potentially have a values, so something like:

     var testCompare = "someValue"

     if (testCompare == model. ....//how can I get the NOT NULL value from ModelTest here for comparison

Body:
What about solution which contains combination of reflection and Linq,

Test Data

var model = new ModelTest() {val1=null, val2="value", val3=null} ;

Usage

var result =
    model.GetType()
    .GetProperties()
    .FirstOrDefault(prop => prop.GetValue(model, null) != null);

Print result

Console.WriteLine(result.GetValue(model));

This is my first attempt with reflection, suggestions are most welcome

.Net fiddle

Note: This is just an alternate solution, less performant. If you are looking for elegant solution, then kindly try other solutions.


问:
How to identify common values in two collections in MarkLogic
I have two XML documents like below and they are in two collections

```<code><Person>
  <Name>A</Name>
  <Age>23</Age>
</Person>
</code>```

another XML is like

```<code><Employee>
  <EName>A</Ename>
  <ECompany>abc</ECompany>
</Employee>
</code>```

above is the sample xmls and these two xmls are in two different collections named person and employee.  I want to identify the element Name from documents in the person collection which matches to EName element from documents in the employee collection.

答:
One way to do this would be to search for the values from the person collection, and use them as criteria to search the employee collection:

```<code>let $person-names := cts:search(/Person/Name, cts:collection-query("person"))
return
  cts:search(/Employee/EName,
    cts:and-query((
      cts:collection-query("employee"),
      cts:element-value-query(xs:QName("EName"), $person-names)
    ))
  )/text()
</code>```

However, that may not work with the scale and size of your docs.

You could use CoRB and break it into 2 phases. Run one job that returns all of the Name values from the docs in the person collection, and write it all out to a file. Then use that file as the inputs for a second job that issues a search against the employee collection for EName values, and returns the value that is written out into the final report. Same concept as above, just broken out into lots of little queries.

If you had a range-index on the Name and Ename elements, then you could use cts:element-values(), return them as a map, and find the intersection of values:

```<code>let $person-names := cts:element-values(xs:QName("Name"), "", "map", cts:collection-query("person"))
let $employee-names := cts:element-values(xs:QName("EName"), "", "map", cts:collection-query("employee"))
return $person-names * $employee-names
</code>```

Body:
I have two XML documents like below and they are in two collections

<Person>
  <Name>A</Name>
  <Age>23</Age>
</Person>

another XML is like

<Employee>
  <EName>A</Ename>
  <ECompany>abc</ECompany>
</Employee>

above is the sample xmls and these two xmls are in two different collections named person and employee.  I want to identify the element Name from documents in the person collection which matches to EName element from documents in the employee collection.

Body:
One way to do this would be to search for the values from the person collection, and use them as criteria to search the employee collection:

let $person-names := cts:search(/Person/Name, cts:collection-query("person"))
return
  cts:search(/Employee/EName,
    cts:and-query((
      cts:collection-query("employee"),
      cts:element-value-query(xs:QName("EName"), $person-names)
    ))
  )/text()

However, that may not work with the scale and size of your docs.

You could use CoRB and break it into 2 phases. Run one job that returns all of the Name values from the docs in the person collection, and write it all out to a file. Then use that file as the inputs for a second job that issues a search against the employee collection for EName values, and returns the value that is written out into the final report. Same concept as above, just broken out into lots of little queries.

If you had a range-index on the Name and Ename elements, then you could use cts:element-values(), return them as a map, and find the intersection of values:

let $person-names := cts:element-values(xs:QName("Name"), "", "map", cts:collection-query("person"))
let $employee-names := cts:element-values(xs:QName("EName"), "", "map", cts:collection-query("employee"))
return $person-names * $employee-names


问:
How to run .NET application on linux with console output?
The following dotnet test program does not give any output. The console just remains blank:

```<code>cd ~/Documents/test
dotnet new console
dotnet run
</code>```

The Program.cs generated by default:

```<code>// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
</code>```

And test.csproj:

```<code><Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>
</code>```

What might be wrong, on an ubuntu 20.04, with dotnet installed version:

```<code>~/Documents/test$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.102
 Commit:    02d5242ed7

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /snap/dotnet-sdk/155/sdk/6.0.102/

Host (useful for support):
  Version: 6.0.2
  Commit:  839cdfb0ec

.NET SDKs installed:
  6.0.102 [/snap/dotnet-sdk/155/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.2 [/snap/dotnet-sdk/155/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.2 [/snap/dotnet-sdk/155/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download
</code>```

Maybe it's important I installed the SDK via kubuntu "discovery"?

答:
I could fix it by uninstalling the snap/discovery version, and instead using the microsoft way:

https://learn.microsoft.com/de-de/dotnet/core/install/linux-ubuntu#2004-

Body:
The following dotnet test program does not give any output. The console just remains blank:

cd ~/Documents/test
dotnet new console
dotnet run

The Program.cs generated by default:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

And test.csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

What might be wrong, on an ubuntu 20.04, with dotnet installed version:

~/Documents/test$ dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.102
 Commit:    02d5242ed7

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /snap/dotnet-sdk/155/sdk/6.0.102/

Host (useful for support):
  Version: 6.0.2
  Commit:  839cdfb0ec

.NET SDKs installed:
  6.0.102 [/snap/dotnet-sdk/155/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.2 [/snap/dotnet-sdk/155/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.2 [/snap/dotnet-sdk/155/shared/Microsoft.NETCore.App]

To install additional .NET runtimes or SDKs:
  https://aka.ms/dotnet-download

Maybe it's important I installed the SDK via kubuntu "discovery"?


问:
Delete a node(or more nodes) between others in a linked list C
Hi I'm creating a program for school where I have to:

Create structures

Create functions to print my linked list

Create functions to insert an element to the bottom of the list

Delete duplicate elements.

I created all a part the last one step(delete function). Can you help me to know what is the right way? This is my code:

```<code>#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*STRUCTURE*/
typedef struct punto {
    int x;
    int y;
} PUNTO;

typedef struct quadrato {
    PUNTO v;
    int lato;
} QUADRATO;

typedef struct nodo {
    QUADRATO q;
    struct nodo *next;
} NODO;

/*PRINT LIST*/
void stampaQuadrato(QUADRATO q) {
    printf("The square has the side equal to %d and coordinates of the lower left vertex (%d,%d)\n", q.lato, q.v.x, q.v.y);
}

void stampaLista(NODO *head) {
    if(head->next==NULL) {
        printf("List empty!\n");
    } else {
        while(head->next != NULL) {
            head = head->next;
            stampaQuadrato(head->q);
        }
    }
}

/*ADD*/
QUADRATO creaQuadrato() {

    QUADRATO nuovo;

    printf("Side measurement: ");
    scanf("%d", &nuovo.lato);
    printf("\n");
    printf("Coordinates of the lower left vertex\n");
    printf("x: ");
    scanf("%d", &nuovo.v.x);
    printf("\n");
    printf("y: ");
    scanf("%d", &nuovo.v.y);
    printf("\n");

    return nuovo;

}

void insert(NODO *head) {
    NODO* nuovoNodo = malloc(sizeof(NODO));
    nuovoNodo->q = creaQuadrato();
    if(head==NULL) {
        head = head->next;
        head = nuovoNodo;
    } else {
        while(head->next != NULL) {
            head = head->next;
        }
        head->next = nuovoNodo;
    }
}

/*DELETE*/
void deleteDuplicates(NODO *head) {
    if(head==NULL) {
        printf("There are no element in the list!\n");
    } else {
        while(head->next != NULL) {
            if(head->q.lato == head->next->q.lato &&
               head->q.v.x == head->next->q.v.x &&
               head->q.v.y == head->next->q.v.y) {
                   NODO* nodoQuad = head->next;
                   head->next = nodoQuad->next;
                   //head->next = head->next->next;
                   free(nodoQuad);
                   printf("Element deleted!\n");
               } else {
                   head = head->next;
               }
        }
    }
}

int main() {
    NODO *head = malloc(sizeof(NODO));
    head->next = NULL;
    int scelta = -1;

    while(scelta != 0) {
        printf("Choose one\n");
        printf("Press 1 --> See list\n");
        printf("Press 2 --> Insert new square(quadrato)\n");
        printf("Press 3 --> Delete duplicates\n");
        printf("Press 0 --> Stop program\n");
        scanf("%d", &scelta);

        if(scelta==1) {
            stampaLista(head);
        }
        else if(scelta==2) {
            insert(head);
        }
        else if(scelta==3) {
            deleteDuplicates(head);
        }
        else if(scelta==0) {
            printf("See you soon ;)\n");
        }

        }

}
</code>```

答:
For starters initially the list should be empty. So you have to write

```<code>NODO *head = NULL;
</code>```

instead of

```<code>NODO *head = malloc(sizeof(NODO));
</code>```

This while loop

```<code>int scelta = -1;

while(scelta != 0) {
    //...
}
</code>```

should be substituted for do while loop as for example

```<code>do
{
    //...
} while ( scelta != 0 );
</code>```

Within the do while loop instead of using if statements it is better to use switch statement as for example

```<code>do
{
    scelta = 0;

    printf("Choose one\n");
    printf("Press 1 --> See list\n");
    printf("Press 2 --> Insert new square(quadrato)\n");
    printf("Press 3 --> Delete duplicates\n");
    printf("Press 0 --> Stop program\n");
    scanf("%d", &scelta);

    enum { Exit = 0, Stampa = 1, Insert = 2, Delete = 3 };

    switch ( scelta )
    {
    case Exit:
        puts( "See you soon" );
        break;

    case Stampa:
        stampaLista( head );
        break;

    case Insert:
        insert( &head );
        break;

    case Delete:
        deleteDuplicates( head );
        break;

    case default:
        puts( "Invalid input. Try anew." );
        break;
    }
} while ( scelta != 0 );
</code>```

The function insert is incorrect

```<code>void insert(NODO *head) {
    NODO* nuovoNodo = malloc(sizeof(NODO));
    nuovoNodo->q = creaQuadrato();
    if(head==NULL) {
        head = head->next;
        head = nuovoNodo;
    } else {
        while(head->next != NULL) {
            head = head->next;
        }
        head->next = nuovoNodo;
    }
}
</code>```

because it does not change the original pointer head declared in main because it deals with a copy of the value of the passed pointer. Changing the copy does not influence on the original pointer.

Also you forgot to set the data member next to NULL of the created node.

The function can be declared and defined the following way

```<code>int insert( NODO **head )
{
    NODO *nuovoNodo = malloc( sizeof( NODO ) );
    int success = nuovoNodo != NULL;

    if success )
    {
        nuovoNodo->q = creaQuadrato();
        nuovoNodo->next = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = nuovoNodo;
    }

    return success;
}
</code>```

The parameter of the function stampaLista should have the qualifier const

```<code>void stampaLista( const NODO *head )
{
    if ( head == NULL )
    {
        puts( "List empty!" );
    }
    else
    {
        for ( ; head != NULL; head = head->next )
        {
            stampaQuadrato( head->q );
        }
    }
}
</code>```

As for the function deleteDuplicates then it removes only adjacent duplicated nodes. If you want to remove all duplicated nodes (not only adjacent) then the function can be defined the following way

```<code>void deleteDuplicates( NODO *head )
{
    if ( head == NULL )
    {
        puts( "There are no element in the list!" );
    }
    else
    {
        for ( ; head != NULL; head = head->next )
        {
            for ( NODO *current = head; current->next != NULL; )
            {
                if ( head->q.lato == current->next->q.lato &&
                     head->q.v.x  == current->next->q.v.x  &&
                     head->q.v.y  == current->next->q.v.y )
                {
                    NODO *nodoQuad = current->next;
                    current->next = nodoQuad->next;
                    free(nodoQuad);
                    puts( "Element deleted!" );
                }
                else
                {
                    current = current->next;
                }
            }
        }
    }
}
</code>```

Body:
Hi I'm creating a program for school where I have to:

Create structures

Create functions to print my linked list

Create functions to insert an element to the bottom of the list

Delete duplicate elements.

I created all a part the last one step(delete function). Can you help me to know what is the right way? This is my code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*STRUCTURE*/
typedef struct punto {
    int x;
    int y;
} PUNTO;

typedef struct quadrato {
    PUNTO v;
    int lato;
} QUADRATO;

typedef struct nodo {
    QUADRATO q;
    struct nodo *next;
} NODO;

/*PRINT LIST*/
void stampaQuadrato(QUADRATO q) {
    printf("The square has the side equal to %d and coordinates of the lower left vertex (%d,%d)\n", q.lato, q.v.x, q.v.y);
}

void stampaLista(NODO *head) {
    if(head->next==NULL) {
        printf("List empty!\n");
    } else {
        while(head->next != NULL) {
            head = head->next;
            stampaQuadrato(head->q);
        }
    }
}

/*ADD*/
QUADRATO creaQuadrato() {

    QUADRATO nuovo;

    printf("Side measurement: ");
    scanf("%d", &nuovo.lato);
    printf("\n");
    printf("Coordinates of the lower left vertex\n");
    printf("x: ");
    scanf("%d", &nuovo.v.x);
    printf("\n");
    printf("y: ");
    scanf("%d", &nuovo.v.y);
    printf("\n");

    return nuovo;

}

void insert(NODO *head) {
    NODO* nuovoNodo = malloc(sizeof(NODO));
    nuovoNodo->q = creaQuadrato();
    if(head==NULL) {
        head = head->next;
        head = nuovoNodo;
    } else {
        while(head->next != NULL) {
            head = head->next;
        }
        head->next = nuovoNodo;
    }
}

/*DELETE*/
void deleteDuplicates(NODO *head) {
    if(head==NULL) {
        printf("There are no element in the list!\n");
    } else {
        while(head->next != NULL) {
            if(head->q.lato == head->next->q.lato &&
               head->q.v.x == head->next->q.v.x &&
               head->q.v.y == head->next->q.v.y) {
                   NODO* nodoQuad = head->next;
                   head->next = nodoQuad->next;
                   //head->next = head->next->next;
                   free(nodoQuad);
                   printf("Element deleted!\n");
               } else {
                   head = head->next;
               }
        }
    }
}

int main() {
    NODO *head = malloc(sizeof(NODO));
    head->next = NULL;
    int scelta = -1;

    while(scelta != 0) {
        printf("Choose one\n");
        printf("Press 1 --> See list\n");
        printf("Press 2 --> Insert new square(quadrato)\n");
        printf("Press 3 --> Delete duplicates\n");
        printf("Press 0 --> Stop program\n");
        scanf("%d", &scelta);

        if(scelta==1) {
            stampaLista(head);
        }
        else if(scelta==2) {
            insert(head);
        }
        else if(scelta==3) {
            deleteDuplicates(head);
        }
        else if(scelta==0) {
            printf("See you soon ;)\n");
        }

        }

}

Body:
For starters initially the list should be empty. So you have to write

NODO *head = NULL;

instead of

NODO *head = malloc(sizeof(NODO));

This while loop

int scelta = -1;

while(scelta != 0) {
    //...
}

should be substituted for do while loop as for example

do
{
    //...
} while ( scelta != 0 );

Within the do while loop instead of using if statements it is better to use switch statement as for example

do
{
    scelta = 0;

    printf("Choose one\n");
    printf("Press 1 --> See list\n");
    printf("Press 2 --> Insert new square(quadrato)\n");
    printf("Press 3 --> Delete duplicates\n");
    printf("Press 0 --> Stop program\n");
    scanf("%d", &scelta);

    enum { Exit = 0, Stampa = 1, Insert = 2, Delete = 3 };

    switch ( scelta )
    {
    case Exit:
        puts( "See you soon" );
        break;

    case Stampa:
        stampaLista( head );
        break;

    case Insert:
        insert( &head );
        break;

    case Delete:
        deleteDuplicates( head );
        break;

    case default:
        puts( "Invalid input. Try anew." );
        break;
    }
} while ( scelta != 0 );

The function insert is incorrect

void insert(NODO *head) {
    NODO* nuovoNodo = malloc(sizeof(NODO));
    nuovoNodo->q = creaQuadrato();
    if(head==NULL) {
        head = head->next;
        head = nuovoNodo;
    } else {
        while(head->next != NULL) {
            head = head->next;
        }
        head->next = nuovoNodo;
    }
}

because it does not change the original pointer head declared in main because it deals with a copy of the value of the passed pointer. Changing the copy does not influence on the original pointer.

Also you forgot to set the data member next to NULL of the created node.

The function can be declared and defined the following way

int insert( NODO **head )
{
    NODO *nuovoNodo = malloc( sizeof( NODO ) );
    int success = nuovoNodo != NULL;

    if success )
    {
        nuovoNodo->q = creaQuadrato();
        nuovoNodo->next = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = nuovoNodo;
    }

    return success;
}

The parameter of the function stampaLista should have the qualifier const

void stampaLista( const NODO *head )
{
    if ( head == NULL )
    {
        puts( "List empty!" );
    }
    else
    {
        for ( ; head != NULL; head = head->next )
        {
            stampaQuadrato( head->q );
        }
    }
}

As for the function deleteDuplicates then it removes only adjacent duplicated nodes. If you want to remove all duplicated nodes (not only adjacent) then the function can be defined the following way

void deleteDuplicates( NODO *head )
{
    if ( head == NULL )
    {
        puts( "There are no element in the list!" );
    }
    else
    {
        for ( ; head != NULL; head = head->next )
        {
            for ( NODO *current = head; current->next != NULL; )
            {
                if ( head->q.lato == current->next->q.lato &&
                     head->q.v.x  == current->next->q.v.x  &&
                     head->q.v.y  == current->next->q.v.y )
                {
                    NODO *nodoQuad = current->next;
                    current->next = nodoQuad->next;
                    free(nodoQuad);
                    puts( "Element deleted!" );
                }
                else
                {
                    current = current->next;
                }
            }
        }
    }
}


问:
How to produce proper json error response for php fatal error in Laravel 8+
I need to produce some proper custom error response in json format when I receive php fatal error instead of standard 500 in Laravel 8+.

How can I achieve the this outcome.

答: You can use Exception. Read the documentation</p>


问:
Where do I define px to em mapping?
I heard from w3schools that 1 em = 16px.
http://www.w3schools.com/css/css_font.asp

However, in my Jekyll site

http://madhur.github.com

The standard font in paragraph is 12px even though I have set font-size: 100% in body and font-size: 1em.

Am I missing something?

答: At line 27 of global.css the font-size of body has been overridden to 76%, 16px*0.76 = 12.16px

Title: Where do I define px to em mapping?


问:
Problem with Logging Module in Google Colab
I have a python script with an error handling using the logging module. Although this python script works when imported to google colab, it doesn't log the errors in the log file.

As an experiment, I tried this following script in google colab just to see if it writes log at all

```<code>import logging
logging.basicConfig(filename="log_file_test.log",
                            filemode='a',
                            format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                            datefmt='%H:%M:%S',
                            level=logging.DEBUG)

logging.info("This is a test log ..")
</code>```

To my dismay, it didn't even create a log file named log_file_test.log. I tried running the same script locally and it did produce a file log_file_test.log with the following text

13:20:53,441 root INFO This is a test log ..

What is it that I am missing here?
For the time being, I am replacing the error logs with print statements, but I assume that there must be a workaround to this.

答:
logging.basicConfig can be run just once*

Any subsequent call to basicConfig is ignored.

* unless you are in Python 3.8 and use the flag force=True

```<code>logging.basicConfig(filename='app.log',
                    level=logging.DEBUG,
                    force=True, # Resets any previous configuration
                    )
</code>```

Workarounds (2)

(1) You can easily reset the Colab workspace with this command

```<code>exit
</code>```

Wait for it to come back and try your commands again.

(2) But, if you plan to do the reset more than once and/or are learning to use logging, maybe it is better to use %%python magic to run the entire cell in a subprocess. See photo below.

What is it that I am missing here?

Deeper understanding of how logging works. It is a bit tricky, but there are many good webs explaining the gotchas.

In Colab

https://realpython.com/python-logging

Body:
I have a python script with an error handling using the logging module. Although this python script works when imported to google colab, it doesn't log the errors in the log file.

As an experiment, I tried this following script in google colab just to see if it writes log at all

import logging
logging.basicConfig(filename="log_file_test.log",
                            filemode='a',
                            format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                            datefmt='%H:%M:%S',
                            level=logging.DEBUG)

logging.info("This is a test log ..")

To my dismay, it didn't even create a log file named log_file_test.log. I tried running the same script locally and it did produce a file log_file_test.log with the following text

13:20:53,441 root INFO This is a test log ..

What is it that I am missing here?
For the time being, I am replacing the error logs with print statements, but I assume that there must be a workaround to this.

Body:
logging.basicConfig can be run just once*

Any subsequent call to basicConfig is ignored.

* unless you are in Python 3.8 and use the flag force=True

logging.basicConfig(filename='app.log',
                    level=logging.DEBUG,
                    force=True, # Resets any previous configuration
                    )

Workarounds (2)

(1) You can easily reset the Colab workspace with this command

exit

Wait for it to come back and try your commands again.

(2) But, if you plan to do the reset more than once and/or are learning to use logging, maybe it is better to use %%python magic to run the entire cell in a subprocess. See photo below.

What is it that I am missing here?

Deeper understanding of how logging works. It is a bit tricky, but there are many good webs explaining the gotchas.

In Colab

https://realpython.com/python-logging


问:
Laravel query for deleting duplicated users which don't have any roles
I have users with duplicate email addresses in users table but not all of them have assigned roles in the role_user table. My task is to delete those records from the users that do not have any assigned roles AND it is a duplicate email address.

There are two tables that are involved in this query (there is also a roles table but that isn't relevant):

users (id, name, email, created_at, deleted_at)

role_user (user_id, role_id, email, created_at, updated_at)

Example:

user record 1

id - 1

name - John Smith

email - john.smith@test.com

created_at 2021-12-15 14:37:00

updated_at 2021-12-15 14:37:00

deleted_at NULL

role_user record 1

user_id - 1

role_id - 1

created_at 2021-12-15 14:37:00

updated_at 2021-12-15 14:37:00

user record 2

id - 2

name - John Smith

email - john.smith@test.com

created_at 2022-02-08 17:30:00

updated_at 2021-12-15 14:37:00

deleted_at NULL

The user record above doesn't have any assigned roles (so no record for them in role_user)

I would need a query to delete the above user (id = 2) and any others like this.

I have already made a start on getting the duplicate users:

```<code>$duplicates = DB::table('users')
    ->select('name', DB::raw('LOWER(email)'))
    ->groupBy('name', DB::raw('LOWER(email)'))
    ->havingRaw('COUNT(*) > 1')
    ->get();

DB::table('users')
    ->whereIn('email', $duplicates->pluck('email'))
    ->whereNotExists(function ($query) {
        $query->select(DB::raw(1))
            ->from('users as u')
            ->where(function ($query) {
                   $query->where('email', DB::raw('users.email'))
                       ->where('id', '<', DB::raw('users.id'));
                   })
            ->whereNull('deleted_at')
            ->limit(1);
    })->update(['deleted_at' => now()]);
</code>```

The query can be written using Eloquent or the query builder.

I need help with deleting the relevant users please.

答:
You can perform a single query to delete duplicate records that don't have role like this i think:</p>
```<code>User::whereNotIn('id', function($query) {
    $query->select('user_id')
      ->from('role_user');
  })->whereIn('email', function($query){
    $query->select('email')
      ->from('users')
      ->groupBy(DB::raw('LOWER(email)'))
      ->havingRaw('count(*) > 0')
  })->delete();
</code>```

Body:
I have users with duplicate email addresses in users table but not all of them have assigned roles in the role_user table. My task is to delete those records from the users that do not have any assigned roles AND it is a duplicate email address.

There are two tables that are involved in this query (there is also a roles table but that isn't relevant):

users (id, name, email, created_at, deleted_at)

role_user (user_id, role_id, email, created_at, updated_at)

Example:

user record 1

id - 1

name - John Smith

email - john.smith@test.com

created_at 2021-12-15 14:37:00

updated_at 2021-12-15 14:37:00

deleted_at NULL

role_user record 1

user_id - 1

role_id - 1

created_at 2021-12-15 14:37:00

updated_at 2021-12-15 14:37:00

user record 2

id - 2

name - John Smith

email - john.smith@test.com

created_at 2022-02-08 17:30:00

updated_at 2021-12-15 14:37:00

deleted_at NULL

The user record above doesn't have any assigned roles (so no record for them in role_user)

I would need a query to delete the above user (id = 2) and any others like this.

I have already made a start on getting the duplicate users:

$duplicates = DB::table('users')
    ->select('name', DB::raw('LOWER(email)'))
    ->groupBy('name', DB::raw('LOWER(email)'))
    ->havingRaw('COUNT(*) > 1')
    ->get();

DB::table('users')
    ->whereIn('email', $duplicates->pluck('email'))
    ->whereNotExists(function ($query) {
        $query->select(DB::raw(1))
            ->from('users as u')
            ->where(function ($query) {
                   $query->where('email', DB::raw('users.email'))
                       ->where('id', '<', DB::raw('users.id'));
                   })
            ->whereNull('deleted_at')
            ->limit(1);
    })->update(['deleted_at' => now()]);

The query can be written using Eloquent or the query builder.

I need help with deleting the relevant users please.

Body:
You can perform a single query to delete duplicate records that don't have role like this i think:

User::whereNotIn('id', function($query) {
    $query->select('user_id')
      ->from('role_user');
  })->whereIn('email', function($query){
    $query->select('email')
      ->from('users')
      ->groupBy(DB::raw('LOWER(email)'))
      ->havingRaw('count(*) > 0')
  })->delete();


问:
Server side includes alternative
I have a static site hosted on GitHub Pages which is starting to grow in size. Normally I would use server side includes (<?php include('path to file'); ?>) to bring in header, footer and any navigation files. However php doesn't run on GitHub Pages.

Is HTML5 embedding which adopts a sort of iFrame technique my only option here?

I have seen threads such as this, this, this, this however they do not seem to apply for GitHub pages.

Not really ideal.

Thanks.

答:
I wrote two bashscripts that does what you are looking for (same reason you are askimg actually). Right now it is extremly basic, but it may be helpful for you. Documentation is nonexistamt, but should be easy to figure out and make work for your site.

https://gitlab.com/frc-team-8733/website/-/tree/master/tools

Title: Server side includes alternative


问:
Route live audio from line-in to AirPods?
Is there a way to route the audio coming from the wired line-in input directly to AirPods?

Currently, I'm creating a .playAndRecord audio session. Paired the AirPods. Later on, with AVAudioEngine I connect the input device directly to the output device.

```<code>engine.connect(
    engine.inputNode,
    to: engine.outputNode,
    format: engine.inputNode.inputFormat(forBus: 0)
)
</code>```

Works nicely, I can hear the live (!) sound from the AirPods microphone directly in my ears.  But then I connect the line-in cable, unfortunately, it overrides the output as well to the line-in (I can read the metering levels nicely, though). If I connect the AirPods, then again, both the input and the output change to AirPods.

Is there a way to reroute the output device to AirPods, but keep the input device unchanged?

UPDATE: I tried set the input port (to line-in) manually using setPreferredInput, but as soon as the input is selected, the output is also get adjusted (to the wired device).

UPDATE: I tried routing both with AVRoutePickerView and MPVolumeView, but all yielded the same result. If I pick a new output, the input gets modified as well.

UPDATE: AudioBus app does this, I can set wired headphones as input, and AirPods as output, works like a charm. So it is definitely possible, I just have no idea what API to use. Actually, neither AudioBus can share the audio to two sets of AirPods.

答:
Yes!  However, it only works if the audio session is created with the allowBluetoothA2DP  option (according to @RobNapier above). It is an output-only profile, therefore it does not route input from the Bluetooth devices at all.

A2DP is a stereo, output-only profile intended for higher bandwidth audio use cases, such as music playback. The system automatically routes to A2DP ports if you configure an app’s audio session to use the ambient, soloAmbient, or playback categories.

Starting with iOS 10.0, apps using the playAndRecord category may also allow routing output to paired Bluetooth A2DP devices. To enable this behavior, pass this category option when setting your audio session’s category.

You can make it work with a bare-bones sound manager something like below.

```<code>class Sound {

    ...

    private var session: AVAudioSession {
        AVAudioSession.sharedInstance()
    }

    private let engine = AVAudioEngine()

    init() {
        setupAudioSession()
    }

    func setupAudioSession() {
        do {
            try session.setCategory(
                .playAndRecord,
                options: [
                    .allowBluetoothA2DP, //
                    .allowAirPlay
                ]
            )
            try session.setActive(true)
        } catch {
            print("Could not configure and activate session. \(error)")
        }
    }

    func start() {
        engine.connect(
            engine.inputNode,
            to: engine.outputNode,
            format: engine.inputNode.inputFormat(forBus: 0)
        )
        do {
            try engine.start()
        } catch {
            print("Could not start engine. \(error)")
        }
    }

    ...
}
</code>```

If you put a MPVolumeView somewhere on the UI, then you can explicitly select the route to bluetooth devices (and more). But I guess even without that you can change the route by simply physically connect/disconnect the devices themselves.

Body:
Is there a way to route the audio coming from the wired line-in input directly to AirPods?

Currently, I'm creating a .playAndRecord audio session. Paired the AirPods. Later on, with AVAudioEngine I connect the input device directly to the output device.

engine.connect(
    engine.inputNode,
    to: engine.outputNode,
    format: engine.inputNode.inputFormat(forBus: 0)
)

Works nicely, I can hear the live (!) sound from the AirPods microphone directly in my ears.  But then I connect the line-in cable, unfortunately, it overrides the output as well to the line-in (I can read the metering levels nicely, though). If I connect the AirPods, then again, both the input and the output change to AirPods.

Is there a way to reroute the output device to AirPods, but keep the input device unchanged?

UPDATE: I tried set the input port (to line-in) manually using setPreferredInput, but as soon as the input is selected, the output is also get adjusted (to the wired device).

UPDATE: I tried routing both with AVRoutePickerView and MPVolumeView, but all yielded the same result. If I pick a new output, the input gets modified as well.

UPDATE: AudioBus app does this, I can set wired headphones as input, and AirPods as output, works like a charm. So it is definitely possible, I just have no idea what API to use. Actually, neither AudioBus can share the audio to two sets of AirPods.

Body:
Yes!  However, it only works if the audio session is created with the allowBluetoothA2DP  option (according to @RobNapier above). It is an output-only profile, therefore it does not route input from the Bluetooth devices at all.

A2DP is a stereo, output-only profile intended for higher bandwidth audio use cases, such as music playback. The system automatically routes to A2DP ports if you configure an app’s audio session to use the ambient, soloAmbient, or playback categories.

Starting with iOS 10.0, apps using the playAndRecord category may also allow routing output to paired Bluetooth A2DP devices. To enable this behavior, pass this category option when setting your audio session’s category.

You can make it work with a bare-bones sound manager something like below.

class Sound {

    ...

    private var session: AVAudioSession {
        AVAudioSession.sharedInstance()
    }

    private let engine = AVAudioEngine()

    init() {
        setupAudioSession()
    }

    func setupAudioSession() {
        do {
            try session.setCategory(
                .playAndRecord,
                options: [
                    .allowBluetoothA2DP, //
                    .allowAirPlay
                ]
            )
            try session.setActive(true)
        } catch {
            print("Could not configure and activate session. \(error)")
        }
    }

    func start() {
        engine.connect(
            engine.inputNode,
            to: engine.outputNode,
            format: engine.inputNode.inputFormat(forBus: 0)
        )
        do {
            try engine.start()
        } catch {
            print("Could not start engine. \(error)")
        }
    }

    ...
}

If you put a MPVolumeView somewhere on the UI, then you can explicitly select the route to bluetooth devices (and more). But I guess even without that you can change the route by simply physically connect/disconnect the devices themselves.


问:
Why are my firebase storage security rules are not enforcing and letting users upload images over the limit?
I have setup my storage security rules to only allow authenticated users to post images that are less than 3mb with the following rule:

```<code>rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
          // Only allow uploads of any image file that's less than 3MB
      allow write: if request.resource.size < 3 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
      allow read, write: if request.auth != null;
    }
  }
}
</code>```

However, I just tested from my client and I was able to upload a picture that is 14mb. I have given plenty of time for security rules to set.

How did I bypass this rule?

答:
You also have allow read, write: if request.auth != null; which overrides the previous one. Try removing write from 2nd line:

```<code>match /{allPaths=**} {
  // Only allow uploads of any image file that's less than 3MB
  allow write: if request.resource.size < 3 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
  allow read: if request.auth != null;
}
</code>```

Body:
I have setup my storage security rules to only allow authenticated users to post images that are less than 3mb with the following rule:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
          // Only allow uploads of any image file that's less than 3MB
      allow write: if request.resource.size < 3 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
      allow read, write: if request.auth != null;
    }
  }
}

However, I just tested from my client and I was able to upload a picture that is 14mb. I have given plenty of time for security rules to set.

How did I bypass this rule?

Body:
You also have allow read, write: if request.auth != null; which overrides the previous one. Try removing write from 2nd line:

match /{allPaths=**} {
  // Only allow uploads of any image file that's less than 3MB
  allow write: if request.resource.size < 3 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
  allow read: if request.auth != null;
}


问:
Sass loader and webpack 4
How to use sass loader with webpack 4? I read a lot about this and most sites recomended to use ExtractTextPlugin, but ExtractTextPlugin doesn't work with webpack 4.

I wrote following webpack.config.js:

```<code>const path = require('path');
const ClosureCompilerPlugin = require('webpack-closure-compiler');

module.exports = {
    module: {
        rules: [
            {
             test: /\.scss$/,
             use: [{
                 loader: "style-loader"
             }, {
                 loader: "css-loader"
             }, {
                 loader: "sass-loader"
             }]
            }
        ]
    },
    plugins: [
        new ClosureCompilerPlugin({
            compiler: {
                language_in: 'ECMASCRIPT6',
                language_out: 'ECMASCRIPT3',
                compilation_level: 'ADVANCED'
            },
            concurrency: 3,
        })
    ]
};
</code>```

Output .js file works well, but my .scss didn't compile to css. I'm tried to add entry points:

```<code>entry: {
    stylesheet: path.resolve('src', 'scss/styles.scss'),
    main: path.resolve('src', 'index.js')
}
</code>```

and after this my styles.scss compiles to stylesheet.js, but i not to .css.

答:
You can use sass-loader@10.1.1 with Webpack 4, if that fits your requirements.

Version 11.0.0 of sass-loader introduced this minimum webpack 5 supported version breaking change. You can see a changelog at https://openbase.com/js/sass-loader/versions

Title: Sass loader and webpack 4

Body:
How to use sass loader with webpack 4? I read a lot about this and most sites recomended to use ExtractTextPlugin, but ExtractTextPlugin doesn't work with webpack 4.

I wrote following webpack.config.js:

const path = require('path');
const ClosureCompilerPlugin = require('webpack-closure-compiler');

module.exports = {
    module: {
        rules: [
            {
             test: /\.scss$/,
             use: [{
                 loader: "style-loader"
             }, {
                 loader: "css-loader"
             }, {
                 loader: "sass-loader"
             }]
            }
        ]
    },
    plugins: [
        new ClosureCompilerPlugin({
            compiler: {
                language_in: 'ECMASCRIPT6',
                language_out: 'ECMASCRIPT3',
                compilation_level: 'ADVANCED'
            },
            concurrency: 3,
        })
    ]
};

Output .js file works well, but my .scss didn't compile to css. I'm tried to add entry points:

entry: {
    stylesheet: path.resolve('src', 'scss/styles.scss'),
    main: path.resolve('src', 'index.js')
}

and after this my styles.scss compiles to stylesheet.js, but i not to .css.


问:
Generate procedural command in batch file
So when you use a batch file to search for substrings in a text file you could use something like the following:

```<code>:SearchOne
findstr %~1 %~2 >> output.txt
exit /b 0
</code>```

If you have multiple search parameter (which all have to match...) you could use:

```<code>:SearchTwo
findstr %~1 %~2 | findstr %~3 >> output.txt
exit /b 0
</code>```

How can I search for multiple numbers of search keys whose numbers aren't fix?

like for example:

for 3: findstr %~1 %~2 | findstr %~3 | findstr %~4 >> output.txt

for 4: findstr %~1 %~2 | findstr %~3 | findstr %~4 | findstr %~5 >> output.txt

and so on...?

答:
This very simple method works fine when the search strings have no quotes, like in your example:

```<code>@echo off
setlocal

for /F "tokens=1,2*" %%a in ("%*") do set "string1=%%b" & set "rest=%%a %%c"
findstr "%string1%" "%rest: =" | findstr "%" >> output.txt
</code>```

In order to appreciate the trick used here, remove the @echo off line and run the program. An example is shown below:

```<code>C:\Tests> multifind.bat file.txt one two three four

C:\Tests> findstr "one" "file.txt"   | findstr "two"   | findstr "three"   | findstr "four"  1>>output.txt
</code>```

Body:
So when you use a batch file to search for substrings in a text file you could use something like the following:

:SearchOne
findstr %~1 %~2 >> output.txt
exit /b 0

If you have multiple search parameter (which all have to match...) you could use:

:SearchTwo
findstr %~1 %~2 | findstr %~3 >> output.txt
exit /b 0

How can I search for multiple numbers of search keys whose numbers aren't fix?

like for example:

for 3: findstr %~1 %~2 | findstr %~3 | findstr %~4 >> output.txt

for 4: findstr %~1 %~2 | findstr %~3 | findstr %~4 | findstr %~5 >> output.txt

and so on...?

Body:
This very simple method works fine when the search strings have no quotes, like in your example:

@echo off
setlocal

for /F "tokens=1,2*" %%a in ("%*") do set "string1=%%b" & set "rest=%%a %%c"
findstr "%string1%" "%rest: =" | findstr "%" >> output.txt

In order to appreciate the trick used here, remove the @echo off line and run the program. An example is shown below:

C:\Tests> multifind.bat file.txt one two three four

C:\Tests> findstr "one" "file.txt"   | findstr "two"   | findstr "three"   | findstr "four"  1>>output.txt


问:
Java: Rationale of the Object class not being declared abstract
Why wasn't the java.lang.Object class declared to be abstract ?

Surely for an Object to be useful it needs added state or behaviour, an Object class is an abstraction, and as such it should have been declared abstract ...  why did they choose not to ?

答:
I am not sure this is the reason, but it allows (or allowed, as there are now better ways of doing it) for an Object to be used as a lock:</p>

```<code>Object lock = new Object();

....

synchronized(lock)
{
}
</code>```

OwnerDisplayName: Ande Turner

ContentLicense: CC BY-SA 2.5

LastEditorDisplayName: Ande

Body:
I am not sure this is the reason, but it allows (or allowed, as there are now better ways of doing it) for an Object to be used as a lock:

Object lock = new Object();

....

synchronized(lock)
{
}

OwnerDisplayName: TofuBeer


问:
Eclipse: exporting configurations from one workspace to another
There is a lot of effort involved in configuring the checkstyle/findbug/codestyle etc in a workspace, so repeating the same for another workspace consumes a lot of time.

Is there any way in which I can simply export the preferences from one workspace to another in eclipse ?

答: They are stored in the .settings folder or in .files at the root of the project. You can commit thwm to you SCM. That would make the project know about the IDE, but that's not a problem if settings don't contain absolute paths.</p>