问:
What is best way to deserialize JSON into multiple models in django rest framework
I am quite new to django rest framework and I would like to discuss what is the best way to implement an API endpoints I am aiming to have.

I have following JSON example:

```<code>[
    {
        'top_lvl_key1': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    },
    {
        'top_lvl_key2': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    },
    {
        'top_lvl_key1': {
            id: 2
            'some_key1': "value"
            'some_key3' : "value"
        }
    },
    {
        'top_lvl_key3': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    }
]
</code>```

and I want to have 3 endpoints

[POST] /insert inserting and parsing the entire JSON to store it into models

[GET] /detail/<top_lvl_key>/ Display all record for specfici top_lvl_key

[GET] /detail//<top_lvl_key>/id/ Display a record for specific top_lvl_key and specific id (only 1 record)

As you can see, I need to store each type of top_lvl_key  to different model so I can retrieve for GET requests. However I am not sure how should I got about serializing the JSON, since the dictionaries of the top_lvl_keys can differ. For example top_lvl_key_1 can sometimes have some_key_1 and some_key_2, but sometimes some_key_1 and some_key_2. So far I have been implementing the models with blank=True, null=True, but I am not sure this is best solution as there a lot of attributes which can be NULL now. Is there a better way to go about this?

Thanks a lot in advance

Body:
I am quite new to django rest framework and I would like to discuss what is the best way to implement an API endpoints I am aiming to have.

I have following JSON example:

[
    {
        'top_lvl_key1': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    },
    {
        'top_lvl_key2': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    },
    {
        'top_lvl_key1': {
            id: 2
            'some_key1': "value"
            'some_key3' : "value"
        }
    },
    {
        'top_lvl_key3': {
            id: 1
            'some_key1': "value"
            'some_key2' : "value"
        }
    }
]

and I want to have 3 endpoints

[POST] /insert inserting and parsing the entire JSON to store it into models

[GET] /detail/<top_lvl_key>/ Display all record for specfici top_lvl_key

[GET] /detail//<top_lvl_key>/id/ Display a record for specific top_lvl_key and specific id (only 1 record)

As you can see, I need to store each type of top_lvl_key  to different model so I can retrieve for GET requests. However I am not sure how should I got about serializing the JSON, since the dictionaries of the top_lvl_keys can differ. For example top_lvl_key_1 can sometimes have some_key_1 and some_key_2, but sometimes some_key_1 and some_key_2. So far I have been implementing the models with blank=True, null=True, but I am not sure this is best solution as there a lot of attributes which can be NULL now. Is there a better way to go about this?

Thanks a lot in advance


来源: stackexchange

问:
Python 3 Spyder Xarray: Why is the same NetCDF file loaded everytime (within a loop, and defining different variables)
I want to load the files here: https://thredds.aodn.org.au/thredds/catalog/IMOS/SRS/SST/ghrsst/L3S-3d/day/1992/catalog.html and store them in a list using xarray. But instead of being on thredds, the files are saved on a remote server that I mount locally and access.

Here is my code to load in the files in a loop:

```<code>    # 'file_paths_on_server' below is a list of file paths

    # load in data
    data = []
    for n in range(len(file_paths_on_server)):
        ds = xr.open_dataset(file_paths_on_server[n], cache=False).load();
        data.append(ds)
        ds.close()
</code>```

However, the same NetCDF file (the first one in the loop) is loaded in at every iteration. So I have a list of the same NetCDF file loaded in.

I tried the following outside of a loop too:

```<code>a = xr.open_dataset(file_paths_on_server[0], cache=False).load()
b = xr.open_dataset(file_paths_on_server[1], cache=False).load()
</code>```

But both a and b are the same NetCDF file loaded in as a dataset. I have checked that `file_paths_on_server' varies, and it does.

I am using Python 3 and the Spyder IDE.

```<code>xarray 2022.11.0
netCDF4 1.5.7
Spyder 5.1.5
Python 3.9.7 64-bit
Qt 5.9.7
PyQt5 5.9.2
Windows 10
</code>```

It seems like an issue with the cache, either for Spyder, Python or xarray?

ContentLicense: CC BY-SA 4.0

Body:
I want to load the files here: https://thredds.aodn.org.au/thredds/catalog/IMOS/SRS/SST/ghrsst/L3S-3d/day/1992/catalog.html and store them in a list using xarray. But instead of being on thredds, the files are saved on a remote server that I mount locally and access.

Here is my code to load in the files in a loop:

    # 'file_paths_on_server' below is a list of file paths

    # load in data
    data = []
    for n in range(len(file_paths_on_server)):
        ds = xr.open_dataset(file_paths_on_server[n], cache=False).load();
        data.append(ds)
        ds.close()

However, the same NetCDF file (the first one in the loop) is loaded in at every iteration. So I have a list of the same NetCDF file loaded in.

I tried the following outside of a loop too:

a = xr.open_dataset(file_paths_on_server[0], cache=False).load()
b = xr.open_dataset(file_paths_on_server[1], cache=False).load()

But both a and b are the same NetCDF file loaded in as a dataset. I have checked that `file_paths_on_server' varies, and it does.

I am using Python 3 and the Spyder IDE.

xarray 2022.11.0
netCDF4 1.5.7
Spyder 5.1.5
Python 3.9.7 64-bit
Qt 5.9.7
PyQt5 5.9.2
Windows 10

It seems like an issue with the cache, either for Spyder, Python or xarray?


问:
Calculate project work risk completion rate
Calculate project work risk completion rate (in excel) based on

Deadline

Work effort/work-effort weight

of tasks completed

Given
Project Unit: Milestone-1 - Milestone-4, MVP-1 (includes All milestones)
Work effort for each milestone (e.g. Milestone-1 = 3 points or small work effort, Milestone-2 = 5 or medium, Milestone-3 = 8 or large)
Work-effort weight for each Milestone (in %)
% or # of Completed tasks per a Milestone

How do I include the time in the equation? Say we have a start date and projected due date or duration (e.g. x weeks or days or months), I need to calculate the risk of completing a task (milestone and the entire MVP) on time based on the current # of tasks completed.

In other words, what is the risk (small/medium/large) that a Milestone/Milestones/MVP will be completed on time (say, Mar-31, 2023) based on the number of tasks completed (15 of 40)?

Please let me know if I need to clarify

I really appreciate any help you can provide.

The image is missing the time/deadline value so the risk is inaccurate current view


问:
How to Fully Utilize CPU cores for skopt.forest_minimize
So I have the following code for running skopt.forest_minimize(), but the biggest challenge I am facing right now is that it is taking upwards of days to finish running even just 2 iterations.

SPACE = [skopt.space.Integer(4, max_neighbour, name='n_neighbors', prior='log-uniform'),
            skopt.space.Integer(6, 10, name='nr_cubes', prior='uniform'),
            skopt.space.Categorical(overlap_cat, name='overlap_perc')]

@skopt.utils.use_named_args(SPACE)
    def objective(**params):
        score, scomp = tune_clustering(X_cont=X_cont, df=df, pl_brewer=pl_brewer, **params)
        if score == 0:
            print('saving new scomp')
            with open(scomp_file, 'w') as filehandle:
                json.dump(scomp, filehandle, default = json_default)
        return score

results = skopt.forest_minimize(objective, SPACE, n_calls=1, n_initial_points=1, callback=[scoring])
```

Is it possible to optimize the following code so that it can compute faster? I noticed that it was barely making use of my CPU, highest CPU utilized is about 30% (it's i7 9th gen with
8 cores).

Also a question while I'm at it, is it possible to utilize a GPU for these computational tasks? I have a 3050 that I can use.

Body:
So I have the following code for running skopt.forest_minimize(), but the biggest challenge I am facing right now is that it is taking upwards of days to finish running even just 2 iterations.

SPACE = [skopt.space.Integer(4, max_neighbour, name='n_neighbors', prior='log-uniform'),
            skopt.space.Integer(6, 10, name='nr_cubes', prior='uniform'),
            skopt.space.Categorical(overlap_cat, name='overlap_perc')]

@skopt.utils.use_named_args(SPACE)
    def objective(**params):
        score, scomp = tune_clustering(X_cont=X_cont, df=df, pl_brewer=pl_brewer, **params)
        if score == 0:
            print('saving new scomp')
            with open(scomp_file, 'w') as filehandle:
                json.dump(scomp, filehandle, default = json_default)
        return score

results = skopt.forest_minimize(objective, SPACE, n_calls=1, n_initial_points=1, callback=[scoring])

Is it possible to optimize the following code so that it can compute faster? I noticed that it was barely making use of my CPU, highest CPU utilized is about 30% (it's i7 9th gen with
8 cores).

Also a question while I'm at it, is it possible to utilize a GPU for these computational tasks? I have a 3050 that I can use.


问:
How to bind database from C# code to my xaml file in MVVM sung livechart pie chart? I can't hardcode it, if I add a new project. It should reflect it
```<code>                <lvc:PieChart LegendLocation="Bottom" DataClick="Chart_OnDataClick" Hoverable="False" DataTooltip="{x:Null}">
                    <lvc:PieChart.Series>
                        <lvc:PieSeries Title="Project 1" Values="3" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 2" Values="4" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 3" Values="6" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 4" Values="2" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                    </lvc:PieChart.Series>
                </lvc:PieChart>
</code>```

I do not want to hardcode it like this. It should see what project exists in my database and reflect it. Not sure how to bind it.

So if I my databse is updated to have 10 projects. It should reflect it here regardless of the value, as of now. I am just trying to get the projects to be reflected on the pie chart.

Body:
                <lvc:PieChart LegendLocation="Bottom" DataClick="Chart_OnDataClick" Hoverable="False" DataTooltip="{x:Null}">
                    <lvc:PieChart.Series>
                        <lvc:PieSeries Title="Project 1" Values="3" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 2" Values="4" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 3" Values="6" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                        <lvc:PieSeries Title="Project 4" Values="2" DataLabels="True"
                           LabelPoint="{Binding PointLabel}"/>
                    </lvc:PieChart.Series>
                </lvc:PieChart>

I do not want to hardcode it like this. It should see what project exists in my database and reflect it. Not sure how to bind it.

So if I my databse is updated to have 10 projects. It should reflect it here regardless of the value, as of now. I am just trying to get the projects to be reflected on the pie chart.


问:
Vectorize code that is dependent on a previous calculated value in the same column/series python
Im am trying to vectorize this horrible loop which calculates the average cost of goods and stores it in a list which I then add as a column to my pandas dataframe.  I have to run this against millions have records so it very very slow.  There can be both positive and negative (borrowed goods) inventory. There can never be a 0 price or quantity value which might be obvious. The logic is as follows:

The first record the avg_cost would be the price of the good bought or sold.

If the inventory goes from positive to negative (or vice versa) then avg_cost would be the price of current record that changed it from positive (negative) to negative(positive)

if the quantity/cost increases  inventory in the previous direction (i.e. previous inventory positive and current record is positive or previous inventory negative and current record is negative) then recalculate the average cost.

If current record quantity/cost removes from the direction of the previous inventory but doesn't change the inventory from positive (negative) to negative(positive) then avg_cost is unchanged.

I've tried to vectorize it by breaking down the various scenarios but I get stumped when I have to rely on the previous value of the avg_cost_price.

for example this is fine for scenario 1 & 2.

```<code>df.avg_cost_price.at[0] = df.price.iloc[0]

df['avg_cost_price'] = np.where(((df.inventory >= 0) & (df.inventory_p < 0)) |
((df.inventory <= 0) & (df.inventory_p > 0)), df.price, 0)
</code>```

Thanks in advance.

#Test Dataframe with dummy data

```<code>price = [random.uniform(2,2.50) for _ in range(10)]
quantity = [random.randint(-500,500) for _ in range(20)]
df = pd.DateFrame()
df['price'] = price
df['quantity'] = quantity
df['cost'] = df.price * df.quantity
df['inventory'] = df.quantity.cumsum()
df['inventory_p'] = df.inventory.shift(fill_value=0)

def calc_avg_cost_price(data):
    avg_cost_price_lst = []
    for idx, row in data.iterrows():
        if idx == 0:
            avg_cost_price_lst.append(row['price'])
        elif (row['inventory'] >= 0)  &  (row['inventory_p'] >= 0):
            # if current and previous inventory level is positive
            if row['quantity'] > 0:
                # adjust cost base of newly purchased inventory
                avg_cp = round(((row['inventory_p'] * avg_cost_price_lst[-1]) + row['cost']) / row['inventory'], 3)
                avg_cost_price_lst.append(avg_cp)
            else:
                #cost base of goods does not change as items are sold
                avg_cost_price_lst.append(avg_cost_price_lst[-1])
        elif (row['inventory'] <= 0)  &  (row['inventory_p'] <= 0):
            # if current and previous inventory level is negative (borrowed inventory)
            if row['quantity'] < 0:
                # adjust cost base of borrowed inventory
                avg_cp = round(((row['inventory_p'] * avg_cost_price_lst[-1]) + row['cost']) / row['inventory'], 3)
                avg_cost_price_lst.append(avg_cp)
            else:
                #cost base of borrowed goods does not change as items are bought back
                avg_cost_price_lst.append(avg_cost_price_lst[-1])
        else: # if inventory >=0 (<=0) and inventory < 0 (> 0) then purchase price
            avg_cost_price_lst.append(row['price'])
    return avg_cost_price_lst

df['avg_cost_price'] =  calc_avg_cost_price(df)
</code>```

Body:
Im am trying to vectorize this horrible loop which calculates the average cost of goods and stores it in a list which I then add as a column to my pandas dataframe.  I have to run this against millions have records so it very very slow.  There can be both positive and negative (borrowed goods) inventory. There can never be a 0 price or quantity value which might be obvious. The logic is as follows:

The first record the avg_cost would be the price of the good bought or sold.

If the inventory goes from positive to negative (or vice versa) then avg_cost would be the price of current record that changed it from positive (negative) to negative(positive)

if the quantity/cost increases  inventory in the previous direction (i.e. previous inventory positive and current record is positive or previous inventory negative and current record is negative) then recalculate the average cost.

If current record quantity/cost removes from the direction of the previous inventory but doesn't change the inventory from positive (negative) to negative(positive) then avg_cost is unchanged.

I've tried to vectorize it by breaking down the various scenarios but I get stumped when I have to rely on the previous value of the avg_cost_price.

for example this is fine for scenario 1 & 2.

df.avg_cost_price.at[0] = df.price.iloc[0]

df['avg_cost_price'] = np.where(((df.inventory >= 0) & (df.inventory_p < 0)) |
((df.inventory <= 0) & (df.inventory_p > 0)), df.price, 0)

Thanks in advance.

#Test Dataframe with dummy data

price = [random.uniform(2,2.50) for _ in range(10)]
quantity = [random.randint(-500,500) for _ in range(20)]
df = pd.DateFrame()
df['price'] = price
df['quantity'] = quantity
df['cost'] = df.price * df.quantity
df['inventory'] = df.quantity.cumsum()
df['inventory_p'] = df.inventory.shift(fill_value=0)

def calc_avg_cost_price(data):
    avg_cost_price_lst = []
    for idx, row in data.iterrows():
        if idx == 0:
            avg_cost_price_lst.append(row['price'])
        elif (row['inventory'] >= 0)  &  (row['inventory_p'] >= 0):
            # if current and previous inventory level is positive
            if row['quantity'] > 0:
                # adjust cost base of newly purchased inventory
                avg_cp = round(((row['inventory_p'] * avg_cost_price_lst[-1]) + row['cost']) / row['inventory'], 3)
                avg_cost_price_lst.append(avg_cp)
            else:
                #cost base of goods does not change as items are sold
                avg_cost_price_lst.append(avg_cost_price_lst[-1])
        elif (row['inventory'] <= 0)  &  (row['inventory_p'] <= 0):
            # if current and previous inventory level is negative (borrowed inventory)
            if row['quantity'] < 0:
                # adjust cost base of borrowed inventory
                avg_cp = round(((row['inventory_p'] * avg_cost_price_lst[-1]) + row['cost']) / row['inventory'], 3)
                avg_cost_price_lst.append(avg_cp)
            else:
                #cost base of borrowed goods does not change as items are bought back
                avg_cost_price_lst.append(avg_cost_price_lst[-1])
        else: # if inventory >=0 (<=0) and inventory < 0 (> 0) then purchase price
            avg_cost_price_lst.append(row['price'])
    return avg_cost_price_lst

df['avg_cost_price'] =  calc_avg_cost_price(df)


问:
What does git use to create hashes of commit and tree objects and how?
I have a question about how git creates a hash for commit and tree objects. Hashing for blobs is totally clear to me (it just use SHA1 hash function to the content of some file), but how it works for commits and trees is not clear to me.

I created a local repository with one numbers.txt file and three commits.

git log gives the following:

```<code>commit dc41478273a498485995002d291651b80b81c7fa (HEAD -> master)
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:34 2023 +0100

   two

commit f367cb4266055586bc7bd03ce7ea439f647efe7c
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:26 2023 +0100

   one

commit a3ea6788d27f46adbcd2e3364863eb84fb0037f7
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:03 2023 +0100

   numbers.txt
</code>```

Using the git command git cat-file -p f367cb4266055586bc7bd03ce7ea439f647efe7c (commit message one) I get the following:

```<code>tree 692ea16ed0b42594ae619008d7937e68774c6a74
parent a3ea6788d27f46adbcd2e3364863eb84fb0037f7
author somename <someemail@gmail.com> 1673483066 +0100
committer somename <someemail@gmail.com> 1673483066 +0100

one
</code>```

Copying the above content in the SHA1 function results in 292a45fd8dab8ebeb1ae752c8e84d9168b500c6f (instead of f367cb4266055586bc7bd03ce7ea439f647efe7c).

The same applies when it comes to git tree objects. Using git cat-file -p 692ea16ed0b42594ae619008d7937e68774c6a74 (tree related to the commit used above) results in:

```<code>100644 blob 43dd47ea691c90a5fa7827892c70241913351963    numbers.txt
</code>```

In this case, the SHA1 function gives ba31f041e553e4ff86e504af8b0a7a8169d5c23c (instead of 692ea16ed0b42594ae619008d7937e68774c6a74).

My questions:

How does git create a hash for commit objects AND tree objects?

Am I missing a space or a newline, or should I use some other content altogether?

Body:
I have a question about how git creates a hash for commit and tree objects. Hashing for blobs is totally clear to me (it just use SHA1 hash function to the content of some file), but how it works for commits and trees is not clear to me.

I created a local repository with one numbers.txt file and three commits.

git log gives the following:

commit dc41478273a498485995002d291651b80b81c7fa (HEAD -> master)
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:34 2023 +0100

   two

commit f367cb4266055586bc7bd03ce7ea439f647efe7c
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:26 2023 +0100

   one

commit a3ea6788d27f46adbcd2e3364863eb84fb0037f7
Author: somename <someemail@gmail.com>
Date:   Thu Jan 12 01:24:03 2023 +0100

   numbers.txt

Using the git command git cat-file -p f367cb4266055586bc7bd03ce7ea439f647efe7c (commit message one) I get the following:

tree 692ea16ed0b42594ae619008d7937e68774c6a74
parent a3ea6788d27f46adbcd2e3364863eb84fb0037f7
author somename <someemail@gmail.com> 1673483066 +0100
committer somename <someemail@gmail.com> 1673483066 +0100

one

Copying the above content in the SHA1 function results in 292a45fd8dab8ebeb1ae752c8e84d9168b500c6f (instead of f367cb4266055586bc7bd03ce7ea439f647efe7c).

The same applies when it comes to git tree objects. Using git cat-file -p 692ea16ed0b42594ae619008d7937e68774c6a74 (tree related to the commit used above) results in:

100644 blob 43dd47ea691c90a5fa7827892c70241913351963    numbers.txt

In this case, the SHA1 function gives ba31f041e553e4ff86e504af8b0a7a8169d5c23c (instead of 692ea16ed0b42594ae619008d7937e68774c6a74).

My questions:

How does git create a hash for commit objects AND tree objects?

Am I missing a space or a newline, or should I use some other content altogether?


问:
How to make the change from Binary Formatter to JSON Formatter in unity
I made a save and load system in Unity using System.Runtime.Serialization.Formatters.Binary, but then I learned that binary is "Unsafe" and I need to use JSON instead. How would I make that change for my scripts to work with JSON instead of binary?

I tried fiquring out JSON utility but I could not understand how to implement it here are my scripts

A save interface

```<code>public interface ISavable
{
    object SaveState();
    void LoadState(object state);
}
</code>```

Getting save data

```<code>public class SavableEntity : MonoBehaviour
{
    [SerializeField]public string id;

    public string Id => id;

    [ContextMenu("GenerateID")]
    private void GenerateID()
    {
        id = Guid.NewGuid().ToString();
    }

    public object SaveState()
    {
        var state = new Dictionary<string, object>();
        foreach(var Savable in GetComponents<ISavable>())
        {
            state[Savable.GetType().ToString()] = Savable.SaveState();
        }
        return state;
    }

    public void LoadState(object state)
    {
        var stateDictinary = (Dictionary<string, object>)state;

        foreach (var savable in GetComponents<ISavable>())
        {
            string getTypeName = savable.GetType().ToString();

            if(stateDictinary.TryGetValue(getTypeName, out object savedState))
            {
                savable.LoadState(savedState);
            }
        }
    }
}
</code>```

The script for writing and reading files

```<code>using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class SaveLoadSystem : MonoBehaviour
{
    public string SavePath;

    [ContextMenu("Save")]
    void Save()
    {
        var state = LoadFile();
        SaveState(state);
        SaveFile(state);
    }

    [ContextMenu("Load")]

    private void Load()
    {
        var state = LoadFile();
        LoadState(state);
    }

    public void SaveFile(object state)
    {
        using (var stream = File.Open(SavePath, FileMode.Create))
        {
            var formater = new BinaryFormatter();
            formater.Serialize(stream, state);
        }
    }

    Dictionary<string, object> LoadFile()
    {
        if (!File.Exists(SavePath))
        {
            Debug.Log("No File");
            return new Dictionary<string, object>();
        }
        using (var stream = File.Open(SavePath, FileMode.Open))
        {
            var formater = new BinaryFormatter();
            return (Dictionary<string, object>)formater.Deserialize(stream);
        }
    }

    void SaveState(Dictionary<string, object> state)
    {
        foreach (var savable in FindObjectsOfType<SavableEntity>())
        {
            state[savable.id] = savable.SaveState();
        }
    }

    void LoadState(Dictionary<string, object> state)
    {
        foreach (var savable in FindObjectsOfType<SavableEntity>())
        {
            if(state.TryGetValue(savable.id, out object savedState))
            {
                savable.LoadState(savedState);
            }
        }
    }

    private void Start()
    {
        SavePath = Path.Combine(Application.persistentDataPath, "SlimeCupData.json");
    }
}
</code>```

Body:
I made a save and load system in Unity using System.Runtime.Serialization.Formatters.Binary, but then I learned that binary is "Unsafe" and I need to use JSON instead. How would I make that change for my scripts to work with JSON instead of binary?

I tried fiquring out JSON utility but I could not understand how to implement it here are my scripts

A save interface

public interface ISavable
{
    object SaveState();
    void LoadState(object state);
}

Getting save data

public class SavableEntity : MonoBehaviour
{
    [SerializeField]public string id;

    public string Id => id;

    [ContextMenu("GenerateID")]
    private void GenerateID()
    {
        id = Guid.NewGuid().ToString();
    }

    public object SaveState()
    {
        var state = new Dictionary<string, object>();
        foreach(var Savable in GetComponents<ISavable>())
        {
            state[Savable.GetType().ToString()] = Savable.SaveState();
        }
        return state;
    }

    public void LoadState(object state)
    {
        var stateDictinary = (Dictionary<string, object>)state;

        foreach (var savable in GetComponents<ISavable>())
        {
            string getTypeName = savable.GetType().ToString();

            if(stateDictinary.TryGetValue(getTypeName, out object savedState))
            {
                savable.LoadState(savedState);
            }
        }
    }
}

The script for writing and reading files

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public class SaveLoadSystem : MonoBehaviour
{
    public string SavePath;

    [ContextMenu("Save")]
    void Save()
    {
        var state = LoadFile();
        SaveState(state);
        SaveFile(state);
    }

    [ContextMenu("Load")]

    private void Load()
    {
        var state = LoadFile();
        LoadState(state);
    }

    public void SaveFile(object state)
    {
        using (var stream = File.Open(SavePath, FileMode.Create))
        {
            var formater = new BinaryFormatter();
            formater.Serialize(stream, state);
        }
    }

    Dictionary<string, object> LoadFile()
    {
        if (!File.Exists(SavePath))
        {
            Debug.Log("No File");
            return new Dictionary<string, object>();
        }
        using (var stream = File.Open(SavePath, FileMode.Open))
        {
            var formater = new BinaryFormatter();
            return (Dictionary<string, object>)formater.Deserialize(stream);
        }
    }

    void SaveState(Dictionary<string, object> state)
    {
        foreach (var savable in FindObjectsOfType<SavableEntity>())
        {
            state[savable.id] = savable.SaveState();
        }
    }

    void LoadState(Dictionary<string, object> state)
    {
        foreach (var savable in FindObjectsOfType<SavableEntity>())
        {
            if(state.TryGetValue(savable.id, out object savedState))
            {
                savable.LoadState(savedState);
            }
        }
    }

    private void Start()
    {
        SavePath = Path.Combine(Application.persistentDataPath, "SlimeCupData.json");
    }
}


问:
Error in Plaid Tutorial Live Interactive Coding
I just login into Plaid and trying the live interactive coding in https://plaid.com/tutorials/basics/
after the project is loaded and I click View App, it will hit

server IP address could not be found.

Please help what should I do


问:
Exporting rstudio map as html
I am currently studying Data Analysis with Rstudio at university. In one of the projects I've been asked to create a map using rstudio and then export it to html to hand it over to the teacher. I've tried to do it with different functions or from the viewer from rstudio but I haven't managed to.

I've tried saving it with this function but it didn't work and I couldn't find another one.

```<code>library(htmltools)

save_html(html, nom_aeronau)
</code>```

Could anyone help me with saving it?

Thank you.

Title: Exporting rstudio map as html

Body:
I am currently studying Data Analysis with Rstudio at university. In one of the projects I've been asked to create a map using rstudio and then export it to html to hand it over to the teacher. I've tried to do it with different functions or from the viewer from rstudio but I haven't managed to.

I've tried saving it with this function but it didn't work and I couldn't find another one.

library(htmltools)

save_html(html, nom_aeronau)

Could anyone help me with saving it?

Thank you.


问:
How to pass parameters to dependent class in C# (.Net 6.0) using DI
I'm working on an ASP.NET Core 6.0 Web API project in C#. I'm relatively new to this and dependency injection. So far I've used DI without much problem but I'm struggling to figure out how to pass an argument to a dependent class that is injected.

I have a set of services (ServiceA and ServiceB), which are inherited from a base class which is also a BackgroundService.

The parent class (BaseService) has a the DataProcessor class as a dependency. This processor class requires a constructor argument which indicates the ID of the service (which is available as a property on the corresponding service class).

My classes:

```<code>public abstract class BaseService : BackgroundService
{
    public abstract string ID { get; }
    protected DataProcessor dp;

    protected BaseService(DataProcessor _dp)
    {
        dp = _dp;
    }
}

public class ServiceA : BaseService
{
    public override string ID => "SA";

    public ServiceA(DataProcessor _dp): base(_dp)
    {
    }
}

public class ServiceB : BaseService
{
    public override string ID => "SB";

    public ServiceA(DataProcessor _dp): base(_dp)
    {
    }
}

public class DataProcessor
{
    private string serviceID;

    public DataProcessor(string _serviceID)
    {
        serviceID = _serviceID;
    }
}
</code>```

This is how I configure this on the startup.cs:

```<code>public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<DataProcessor>();

    // Add Service A
    services.AddSingleton<ServiceA>();
    services.AddHostedService<ServiceA>(p =>
    {
        return (ServiceA)p.GetServices<BaseService>().Where(a => a.GetType() == typeof(ServiceA)).First();
    });

    // Add Service B
    services.AddSingleton<ServiceB>();
    services.AddHostedService<ServiceB>(p =>
    {
        return (ServiceB)p.GetServices<BaseService>().Where(a => a.GetType() == typeof(ServiceB)).First();
    });
}
</code>```

The question is: how do I pass the ID property of the Service class to the DataProcessor class?

Note: I've simplified the code and setup for the purpose of the question.

I have tried by creating an Initialize(string ID) method on the DataProcessor class and calling that within the constructor of my BaseService class. This works but I don't like it as a solution, as I have to manually call this Initialize method.

I've searched a lot and read several similar questions/posts, but really couldn't figure it out.

It does seem like a relatively common request, so might be that I'm not using the DI correctly here or that I have the wrong expectation.

Thank you!

Body:
I'm working on an ASP.NET Core 6.0 Web API project in C#. I'm relatively new to this and dependency injection. So far I've used DI without much problem but I'm struggling to figure out how to pass an argument to a dependent class that is injected.

I have a set of services (ServiceA and ServiceB), which are inherited from a base class which is also a BackgroundService.

The parent class (BaseService) has a the DataProcessor class as a dependency. This processor class requires a constructor argument which indicates the ID of the service (which is available as a property on the corresponding service class).

My classes:

public abstract class BaseService : BackgroundService
{
    public abstract string ID { get; }
    protected DataProcessor dp;

    protected BaseService(DataProcessor _dp)
    {
        dp = _dp;
    }
}

public class ServiceA : BaseService
{
    public override string ID => "SA";

    public ServiceA(DataProcessor _dp): base(_dp)
    {
    }
}

public class ServiceB : BaseService
{
    public override string ID => "SB";

    public ServiceA(DataProcessor _dp): base(_dp)
    {
    }
}

public class DataProcessor
{
    private string serviceID;

    public DataProcessor(string _serviceID)
    {
        serviceID = _serviceID;
    }
}

This is how I configure this on the startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<DataProcessor>();

    // Add Service A
    services.AddSingleton<ServiceA>();
    services.AddHostedService<ServiceA>(p =>
    {
        return (ServiceA)p.GetServices<BaseService>().Where(a => a.GetType() == typeof(ServiceA)).First();
    });

    // Add Service B
    services.AddSingleton<ServiceB>();
    services.AddHostedService<ServiceB>(p =>
    {
        return (ServiceB)p.GetServices<BaseService>().Where(a => a.GetType() == typeof(ServiceB)).First();
    });
}

The question is: how do I pass the ID property of the Service class to the DataProcessor class?

Note: I've simplified the code and setup for the purpose of the question.

I have tried by creating an Initialize(string ID) method on the DataProcessor class and calling that within the constructor of my BaseService class. This works but I don't like it as a solution, as I have to manually call this Initialize method.

I've searched a lot and read several similar questions/posts, but really couldn't figure it out.

It does seem like a relatively common request, so might be that I'm not using the DI correctly here or that I have the wrong expectation.

Thank you!


问:
When I run an `npm install`, my package-lock.json removes `bundled: true`
Not sure if I've changed my npm version recently, but I looked at my diffs for pull requests and noticed that my package-lock.json has updated. Now it looks something like this in which the bundle:true is removed and is replaced with a resolved and integrity property.

package-lock.json

```<code>"@mydep": {
    "dependencies": {
       "dep": {
          "version": "2.0.0",
          // "bundled": true, // this is removed
          "resolved": "mynpmregistry",
          "integrity": "sha-190"
        }
    }
}
</code>```

My main question is, why is bundled: true removed?

Body:
Not sure if I've changed my npm version recently, but I looked at my diffs for pull requests and noticed that my package-lock.json has updated. Now it looks something like this in which the bundle:true is removed and is replaced with a resolved and integrity property.

package-lock.json

"@mydep": {
    "dependencies": {
       "dep": {
          "version": "2.0.0",
          // "bundled": true, // this is removed
          "resolved": "mynpmregistry",
          "integrity": "sha-190"
        }
    }
}

My main question is, why is bundled: true removed?


问:
virt-install and qemu-system-aarch64: cannot create vmnet interface: general failure (possibly not enough privileges)
I'm trying to virt-install the following:

```<code>sudo virt-install \                             1
--name host1 \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom ./box.img \
--os-variant ubuntu22.04 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=net0 -device virtio-net-device,netdev=net0,mac=54:54:00:55:54:51' \
--network user
</code>```

and I got the following error:

```<code>ERROR    internal error: process exited while connecting to monitor: 2023-01-12T01:08:04.782892Z qemu-system-aarch64: -netdev vmnet-shared,id=net0: cannot create vmnet interface: general failure (possibly not enough privileges)

</code>```

I've tried to run both libvirtd manually and via the brew services, and I got the same error.

```<code># when I run as a local user
/opt/homebrew/opt/libvirt/sbin/libvirtd -f /opt/homebrew/etc/libvirt/libvirtd.conf
</code>```
```<code># via homebrew services
◼ ~ $ brew services
Name             Status  User File
libvirt          started root ~/Library/LaunchAgents/homebrew.mxcl.libvirt.plist
</code>```

and this is the libvirtd.conf:

```<code>
# Master libvirt daemon configuration file
#

#################################################################
#
# Network connectivity controls
#

# Flag listening for secure TLS connections on the public TCP/IP port.
#
# To enable listening sockets with the 'libvirtd' daemon it's also required to
# pass the '--listen' flag on the commandline of the daemon.
# This is not needed with 'virtproxyd'.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# It is necessary to setup a CA and issue server certificates before
# using this capability.
#
# This is enabled by default, uncomment this to disable it
#listen_tls = 0

# Listen for unencrypted TCP connections on the public TCP/IP port.
#
# To enable listening sockets with the 'libvirtd' daemon it's also required to
# pass the '--listen' flag on the commandline of the daemon.
# This is not needed with 'virtproxyd'.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Using the TCP socket requires SASL authentication by default. Only
# SASL mechanisms which support data encryption are allowed. This is
# DIGEST_MD5 and GSSAPI (Kerberos5)
#
# This is disabled by default, uncomment this to enable it.
#listen_tcp = 1

# Override the port for accepting secure TLS connections
# This can be a port number, or service name
#
# This setting is not required or honoured if using systemd socket
# activation.
#
#tls_port = "16514"

# Override the port for accepting insecure TCP connections
# This can be a port number, or service name
#
# This setting is not required or honoured if using systemd socket
# activation.
#
#tcp_port = "16509"

# Override the default configuration which binds to all network
# interfaces. This can be a numeric IPv4/6 address, or hostname
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# If the libvirtd service is started in parallel with network
# startup (e.g. with systemd), binding to addresses other than
# the wildcards (0.0.0.0/::) might not be available yet.
#
#listen_addr = "192.168.0.1"

#################################################################
#
# UNIX socket access controls
#

# Set the UNIX domain socket group ownership. This can be used to
# allow a 'trusted' set of users access to management capabilities
# without becoming root.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# This is restricted to 'root' by default.
#unix_sock_group = "libvirt"

# Set the UNIX socket permissions for the R/O socket. This is used
# for monitoring VM status only
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows any user. If setting group ownership, you may want to
# restrict this too.
unix_sock_ro_perms = "0777"

# Set the UNIX socket permissions for the R/W socket. This is used
# for full management of VMs
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows only root. If PolicyKit is enabled on the socket,
# the default will change to allow everyone (eg, 0777)
#
# If not using PolicyKit and setting group ownership for access
# control, then you may want to relax this too.
unix_sock_rw_perms = "0770"

# Set the UNIX socket permissions for the admin interface socket.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows only owner (root), do not change it unless you are
# sure to whom you are exposing the access to.
unix_sock_admin_perms = "0700"

# Set the name of the directory in which sockets will be found/created.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
unix_sock_dir = "/opt/homebrew/var/run/libvirt"

#################################################################
#
# Authentication.
#
# There are the following choices available:
#
#  - none: do not perform auth checks. If you can connect to the
#          socket you are allowed. This is suitable if there are
#          restrictions on connecting to the socket (eg, UNIX
#          socket permissions), or if there is a lower layer in
#          the network providing auth (eg, TLS/x509 certificates)
#
#  - sasl: use SASL infrastructure. The actual auth scheme is then
#          controlled from /opt/homebrew/etc/sasl2/libvirt.conf. For the TCP
#          socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
#          For non-TCP or TLS sockets, any scheme is allowed.
#
#  - polkit: use PolicyKit to authenticate. This is only suitable
#            for use on the UNIX sockets. The default policy will
#            require a user to supply their own password to gain
#            full read/write access (aka sudo like), while anyone
#            is allowed read/only access.
#

# Set an authentication scheme for UNIX read-only sockets
#
# By default socket permissions allow anyone to connect
#
# If libvirt was compiled without support for 'polkit', then
# no access control checks are done, but libvirt still only
# allows execution of APIs which don't change state.
#
# If libvirt was compiled with support for 'polkit', then
# the libvirt socket will perform a check with polkit after
# connections. The default policy still allows any local
# user access.
#
# To restrict monitoring of domains you may wish to either
# enable 'sasl' here, or change the polkit policy definition.
#auth_unix_ro = "none"

# Set an authentication scheme for UNIX read-write sockets.
#
# If libvirt was compiled without support for 'polkit', then
# the systemd .socket files will use SocketMode=0600 by default
# thus only allowing root user to connect, and 'auth_unix_rw'
# will default to 'none'.
#
# If libvirt was compiled with support for 'polkit', then
# the systemd .socket files will use SocketMode=0666 which
# allows any user to connect and 'auth_unix_rw' will default
# to 'polkit'. If you disable use of 'polkit' here, then it
# is essential to change the systemd SocketMode parameter
# back to 0600, to avoid an insecure configuration.
#
#auth_unix_rw = "none"

# Change the authentication scheme for TCP sockets.
#
# If you don't enable SASL, then all TCP traffic is cleartext.
# Don't do this outside of a dev/test scenario. For real world
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
# mechanism in /opt/homebrew/etc/sasl2/libvirt.conf
#auth_tcp = "sasl"

# Change the authentication scheme for TLS sockets.
#
# TLS sockets already have encryption provided by the TLS
# layer, and limited authentication is done by certificates
#
# It is possible to make use of any SASL authentication
# mechanism as well, by using 'sasl' for this option
#auth_tls = "none"

# Enforce a minimum SSF value for TCP sockets
#
# The default minimum is currently 56 (single-DES) which will
# be raised to 112 in the future.
#
# This option can be used to set values higher than 112
#tcp_min_ssf = 112

# Change the API access control scheme
#
# By default an authenticated user is allowed access
# to all APIs. Access drivers can place restrictions
# on this. By default the 'nop' driver is enabled,
# meaning no access control checks are done once a
# client has authenticated with libvirtd
#
#access_drivers = [ "polkit" ]

#################################################################
#
# TLS x509 certificate configuration
#

# Use of TLS requires that x509 certificates be issued. The default locations
# for the certificate files is as follows:
#
#   /opt/homebrew/etc/pki/CA/cacert.pem - The CA master certificate
#   /opt/homebrew/etc/pki/libvirt/servercert.pem - The server certificate signed by cacert.pem
#   /opt/homebrew/etc/pki/libvirt/private/serverkey.pem - The server private key
#
# It is possible to override the default locations by altering the 'key_file',
# 'cert_file', and 'ca_file' values and uncommenting them below.
#
# NB, overriding the default of one location requires uncommenting and
# possibly additionally overriding the other settings.
#

# Override the default server key file path
#
#key_file = "/opt/homebrew/etc/pki/libvirt/private/serverkey.pem"

# Override the default server certificate file path
#
#cert_file = "/opt/homebrew/etc/pki/libvirt/servercert.pem"

# Override the default CA certificate path
#
#ca_file = "/opt/homebrew/etc/pki/CA/cacert.pem"

# Specify a certificate revocation list.
#
# Defaults to not using a CRL, uncomment to enable it
#crl_file = "/opt/homebrew/etc/pki/CA/crl.pem"

#################################################################
#
# Authorization controls
#

# Flag to disable verification of our own server certificates
#
# When libvirtd starts it performs some sanity checks against
# its own certificates.
#
# Default is to always run sanity checks. Uncommenting this
# will disable sanity checks which is not a good idea
#tls_no_sanity_certificate = 1

# Flag to disable verification of client certificates
#
# Client certificate verification is the primary authentication mechanism.
# Any client which does not present a certificate signed by the CA
# will be rejected.
#
# Default is to always verify. Uncommenting this will disable
# verification.
#tls_no_verify_certificate = 1

# An access control list of allowed x509 Distinguished Names
# This list may contain wildcards such as
#
#    "C=GB,ST=London,L=London,O=Red Hat,CN=*"
#
# Any * matches any number of consecutive spaces, like a simplified glob(7).
#
# The format of the DN for a particular certificate can be queried
# using:
#
#    virt-pki-query-dn clientcert.pem
#
# NB If this is an empty list, no client can connect, so comment out
# entirely rather than using empty list to disable these checks
#
# By default, no DN's are checked
#tls_allowed_dn_list = ["DN1", "DN2"]

# Override the compile time default TLS priority string. The
# default is usually "NORMAL" unless overridden at build time.
# Only set this is it is desired for libvirt to deviate from
# the global default settings.
#
#tls_priority="NORMAL"

# An access control list of allowed SASL usernames. The format for username
# depends on the SASL authentication mechanism. Kerberos usernames
# look like username@REALM
#
# This list may contain wildcards such as
#
#    "*@EXAMPLE.COM"
#
# See the g_pattern_match function for the format of the wildcards.
#
# https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html
#
# NB If this is an empty list, no client can connect, so comment out
# entirely rather than using empty list to disable these checks
#
# By default, no Username's are checked
#sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]

#################################################################
#
# Processing controls
#

# The maximum number of concurrent client connections to allow
# over all sockets combined.
#max_clients = 5000

# The maximum length of queue of connections waiting to be
# accepted by the daemon. Note, that some protocols supporting
# retransmission may obey this so that a later reattempt at
# connection succeeds.
#max_queued_clients = 1000

# The maximum length of queue of accepted but not yet
# authenticated clients. The default value is 20. Set this to
# zero to turn this feature off.
#max_anonymous_clients = 20

# The minimum limit sets the number of workers to start up
# initially. If the number of active clients exceeds this,
# then more threads are spawned, up to max_workers limit.
# Typically you'd want max_workers to equal maximum number
# of clients allowed
#min_workers = 5
#max_workers = 20

# The number of priority workers. If all workers from above
# pool are stuck, some calls marked as high priority
# (notably domainDestroy) can be executed in this pool.
#prio_workers = 5

# Limit on concurrent requests from a single client
# connection. To avoid one client monopolizing the server
# this should be a small fraction of the global max_workers
# parameter.
#max_client_requests = 5

# Same processing controls, but this time for the admin interface.
# For description of each option, be so kind to scroll few lines
# upwards.

#admin_min_workers = 1
#admin_max_workers = 5
#admin_max_clients = 5
#admin_max_queued_clients = 5
#admin_max_client_requests = 5

#################################################################
#
# Logging controls
#

# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
# basically 1 will log everything possible
#
# WARNING: USE OF THIS IS STRONGLY DISCOURAGED.
#
# WARNING: It outputs too much information to practically read.
# WARNING: The "log_filters" setting is recommended instead.
#
# WARNING: Journald applies rate limiting of messages and so libvirt
# WARNING: will limit "log_level" to only allow values 3 or 4 if
# WARNING: journald is the current output.
#
# WARNING: USE OF THIS IS STRONGLY DISCOURAGED.
#log_level = 3

# Logging filters:
# A filter allows to select a different logging level for a given category
# of logs. The format for a filter is:
#
#    level:match
#
# where 'match' is a string which is matched against the category
# given in the VIR_LOG_INIT() at the top of each libvirt source
# file, e.g., "remote", "qemu", or "util.json". The 'match' in the
# filter matches using shell wildcard syntax (see 'man glob(7)').
# The 'match' is always treated as a substring match. IOW a match
# string 'foo' is equivalent to '*foo*'.
#
# 'level' is the minimal level where matching messages should
#  be logged:
#
#    1: DEBUG
#    2: INFO
#    3: WARNING
#    4: ERROR
#
# Multiple filters can be defined in a single @log_filters, they just need
# to be separated by spaces. Note that libvirt performs "first" match, i.e.
# if there are concurrent filters, the first one that matches will be applied,
# given the order in @log_filters.
#
# A typical need is to capture information from a hypervisor driver,
# public API entrypoints and some of the utility code. Some utility
# code is very verbose and is generally not desired. Taking the QEMU
# hypervisor as an example, a suitable filter string for debugging
# might be to turn off object, json & event logging, but enable the
# rest of the util code:
#
#log_filters="1:qemu 1:libvirt 4:object 4:json 4:event 1:util"

# Logging outputs:
# An output is one of the places to save logging information
# The format for an output can be:
#    level:stderr
#      output goes to stderr
#    level:syslog:name
#      use syslog for the output and use the given name as the ident
#    level:file:file_path
#      output to a file, with the given filepath
#    level:journald
#      output to journald logging system
# In all cases 'level' is the minimal priority, acting as a filter
#    1: DEBUG
#    2: INFO
#    3: WARNING
#    4: ERROR
#
# Multiple outputs can be defined, they just need to be separated by spaces.
# e.g. to log all warnings and errors to syslog under the libvirtd ident:
#log_outputs="3:syslog:libvirtd"

##################################################################
#
# Auditing
#
# This setting allows usage of the auditing subsystem to be altered:
#
#   audit_level == 0  -> disable all auditing
#   audit_level == 1  -> enable auditing, only if enabled on host (default)
#   audit_level == 2  -> enable auditing, and exit if disabled on host
#
#audit_level = 2
#
# If set to 1, then audit messages will also be sent
# via libvirt logging infrastructure. Defaults to 0
#
#audit_logging = 1

###################################################################
# UUID of the host:
# Host UUID is read from one of the sources specified in host_uuid_source.
#
# - 'smbios': fetch the UUID from 'dmidecode -s system-uuid'
# - 'machine-id': fetch the UUID from /etc/machine-id
#
# The host_uuid_source default is 'smbios'. If 'dmidecode' does not provide
# a valid UUID a temporary UUID will be generated.
#
# Another option is to specify host UUID in host_uuid.
#
# Keep the format of the example UUID below. UUID must not have all digits
# be the same.

# NB This default all-zeros UUID will not work. Replace
# it with the output of the 'uuidgen' command and then
# uncomment this entry
#host_uuid = "00000000-0000-0000-0000-000000000000"
#host_uuid_source = "smbios"

###################################################################
# Keepalive protocol:
# This allows libvirtd to detect broken client connections or even
# dead clients.  A keepalive message is sent to a client after
# keepalive_interval seconds of inactivity to check if the client is
# still responding; keepalive_count is a maximum number of keepalive
# messages that are allowed to be sent to the client without getting
# any response before the connection is considered broken.  In other
# words, the connection is automatically closed approximately after
# keepalive_interval * (keepalive_count + 1) seconds since the last
# message received from the client.  If keepalive_interval is set to
# -1, libvirtd will never send keepalive requests; however clients
# can still send them and the daemon will send responses.  When
# keepalive_count is set to 0, connections will be automatically
# closed after keepalive_interval seconds of inactivity without
# sending any keepalive messages.
#
#keepalive_interval = 5
#keepalive_count = 5

#
# These configuration options are no longer used.  There is no way to
# restrict such clients from connecting since they first need to
# connect in order to ask for keepalive.
#
#keepalive_required = 1
#admin_keepalive_required = 1

# Keepalive settings for the admin interface
#admin_keepalive_interval = 5
#admin_keepalive_count = 5

###################################################################
# Open vSwitch:
# This allows to specify a timeout for openvswitch calls made by
# libvirt. The ovs-vsctl utility is used for the configuration and
# its timeout option is set by default to 5 seconds to avoid
# potential infinite waits blocking libvirt.
#
#
</code>```

Now, to make sure that was a privilege error, I ran:

```<code>qemu-system-aarch64 -netdev vmnet-shared,id=net0 -machine virt-2.10
</code>```

which reproduces the error, but:

```<code>sudo qemu-system-aarch64 -netdev vmnet-shared,id=net0 -machine virt-2.10
</code>```

opens a qemu window and I got:

```<code>qemu-system-aarch64: warning: netdev net0 has no peer
</code>```

alright, how could I fix libvirt on Mac OS, installed via homebrew?

```<code>$ brew info libvirt                               1
==> libvirt: stable 8.10.0 (bottled), HEAD
C virtualization API
https://libvirt.org/
/opt/homebrew/Cellar/libvirt/8.10.0 (587 files, 40.8MB) *
  Poured from bottle on 2023-01-11 at 19:20:38
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libvirt.rb
License: LGPL-2.1-or-later and GPL-2.0-or-later
==> Dependencies
Build: docutils ✘, meson ✘, ninja ✘, perl ✘, pkg-config ✔, python@3.11 ✔, rpcgen ✘
Required: gettext ✔, glib ✔, gnu-sed ✔, gnutls ✔, grep ✔, libgcrypt ✔, libiscsi ✔, libssh2 ✔, yajl ✔
==> Options
--HEAD
    Install HEAD version
==> Caveats
To restart libvirt after an upgrade:
  brew services restart libvirt
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/libvirt/sbin/libvirtd -f /opt/homebrew/etc/libvirt/libvirtd.conf
==> Analytics
install: 4,452 (30 days), 18,333 (90 days), 69,415 (365 days)
install-on-request: 3,222 (30 days), 13,494 (90 days), 52,022 (365 days)
build-error: 4 (30 days)
</code>```

Update

Maybe I've found the source of the problem here, if anyone could confirm

Body:
I'm trying to virt-install the following:

sudo virt-install \                             1
--name host1 \
--memory 2048 \
--vcpus 2 \
--disk size=30 \
--cdrom ./box.img \
--os-variant ubuntu22.04 \
--virt-type hvf \
--qemu-commandline='-M highmem=off -netdev vmnet-shared,id=net0 -device virtio-net-device,netdev=net0,mac=54:54:00:55:54:51' \
--network user

and I got the following error:

ERROR    internal error: process exited while connecting to monitor: 2023-01-12T01:08:04.782892Z qemu-system-aarch64: -netdev vmnet-shared,id=net0: cannot create vmnet interface: general failure (possibly not enough privileges)

I've tried to run both libvirtd manually and via the brew services, and I got the same error.

# when I run as a local user
/opt/homebrew/opt/libvirt/sbin/libvirtd -f /opt/homebrew/etc/libvirt/libvirtd.conf

# via homebrew services
◼ ~ $ brew services
Name             Status  User File
libvirt          started root ~/Library/LaunchAgents/homebrew.mxcl.libvirt.plist

and this is the libvirtd.conf:

# Master libvirt daemon configuration file
#

#################################################################
#
# Network connectivity controls
#

# Flag listening for secure TLS connections on the public TCP/IP port.
#
# To enable listening sockets with the 'libvirtd' daemon it's also required to
# pass the '--listen' flag on the commandline of the daemon.
# This is not needed with 'virtproxyd'.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# It is necessary to setup a CA and issue server certificates before
# using this capability.
#
# This is enabled by default, uncomment this to disable it
#listen_tls = 0

# Listen for unencrypted TCP connections on the public TCP/IP port.
#
# To enable listening sockets with the 'libvirtd' daemon it's also required to
# pass the '--listen' flag on the commandline of the daemon.
# This is not needed with 'virtproxyd'.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Using the TCP socket requires SASL authentication by default. Only
# SASL mechanisms which support data encryption are allowed. This is
# DIGEST_MD5 and GSSAPI (Kerberos5)
#
# This is disabled by default, uncomment this to enable it.
#listen_tcp = 1

# Override the port for accepting secure TLS connections
# This can be a port number, or service name
#
# This setting is not required or honoured if using systemd socket
# activation.
#
#tls_port = "16514"

# Override the port for accepting insecure TCP connections
# This can be a port number, or service name
#
# This setting is not required or honoured if using systemd socket
# activation.
#
#tcp_port = "16509"

# Override the default configuration which binds to all network
# interfaces. This can be a numeric IPv4/6 address, or hostname
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# If the libvirtd service is started in parallel with network
# startup (e.g. with systemd), binding to addresses other than
# the wildcards (0.0.0.0/::) might not be available yet.
#
#listen_addr = "192.168.0.1"

#################################################################
#
# UNIX socket access controls
#

# Set the UNIX domain socket group ownership. This can be used to
# allow a 'trusted' set of users access to management capabilities
# without becoming root.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# This is restricted to 'root' by default.
#unix_sock_group = "libvirt"

# Set the UNIX socket permissions for the R/O socket. This is used
# for monitoring VM status only
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows any user. If setting group ownership, you may want to
# restrict this too.
unix_sock_ro_perms = "0777"

# Set the UNIX socket permissions for the R/W socket. This is used
# for full management of VMs
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows only root. If PolicyKit is enabled on the socket,
# the default will change to allow everyone (eg, 0777)
#
# If not using PolicyKit and setting group ownership for access
# control, then you may want to relax this too.
unix_sock_rw_perms = "0770"

# Set the UNIX socket permissions for the admin interface socket.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
# Default allows only owner (root), do not change it unless you are
# sure to whom you are exposing the access to.
unix_sock_admin_perms = "0700"

# Set the name of the directory in which sockets will be found/created.
#
# This setting is not required or honoured if using systemd socket
# activation.
#
unix_sock_dir = "/opt/homebrew/var/run/libvirt"

#################################################################
#
# Authentication.
#
# There are the following choices available:
#
#  - none: do not perform auth checks. If you can connect to the
#          socket you are allowed. This is suitable if there are
#          restrictions on connecting to the socket (eg, UNIX
#          socket permissions), or if there is a lower layer in
#          the network providing auth (eg, TLS/x509 certificates)
#
#  - sasl: use SASL infrastructure. The actual auth scheme is then
#          controlled from /opt/homebrew/etc/sasl2/libvirt.conf. For the TCP
#          socket only GSSAPI & DIGEST-MD5 mechanisms will be used.
#          For non-TCP or TLS sockets, any scheme is allowed.
#
#  - polkit: use PolicyKit to authenticate. This is only suitable
#            for use on the UNIX sockets. The default policy will
#            require a user to supply their own password to gain
#            full read/write access (aka sudo like), while anyone
#            is allowed read/only access.
#

# Set an authentication scheme for UNIX read-only sockets
#
# By default socket permissions allow anyone to connect
#
# If libvirt was compiled without support for 'polkit', then
# no access control checks are done, but libvirt still only
# allows execution of APIs which don't change state.
#
# If libvirt was compiled with support for 'polkit', then
# the libvirt socket will perform a check with polkit after
# connections. The default policy still allows any local
# user access.
#
# To restrict monitoring of domains you may wish to either
# enable 'sasl' here, or change the polkit policy definition.
#auth_unix_ro = "none"

# Set an authentication scheme for UNIX read-write sockets.
#
# If libvirt was compiled without support for 'polkit', then
# the systemd .socket files will use SocketMode=0600 by default
# thus only allowing root user to connect, and 'auth_unix_rw'
# will default to 'none'.
#
# If libvirt was compiled with support for 'polkit', then
# the systemd .socket files will use SocketMode=0666 which
# allows any user to connect and 'auth_unix_rw' will default
# to 'polkit'. If you disable use of 'polkit' here, then it
# is essential to change the systemd SocketMode parameter
# back to 0600, to avoid an insecure configuration.
#
#auth_unix_rw = "none"

# Change the authentication scheme for TCP sockets.
#
# If you don't enable SASL, then all TCP traffic is cleartext.
# Don't do this outside of a dev/test scenario. For real world
# use, always enable SASL and use the GSSAPI or DIGEST-MD5
# mechanism in /opt/homebrew/etc/sasl2/libvirt.conf
#auth_tcp = "sasl"

# Change the authentication scheme for TLS sockets.
#
# TLS sockets already have encryption provided by the TLS
# layer, and limited authentication is done by certificates
#
# It is possible to make use of any SASL authentication
# mechanism as well, by using 'sasl' for this option
#auth_tls = "none"

# Enforce a minimum SSF value for TCP sockets
#
# The default minimum is currently 56 (single-DES) which will
# be raised to 112 in the future.
#
# This option can be used to set values higher than 112
#tcp_min_ssf = 112

# Change the API access control scheme
#
# By default an authenticated user is allowed access
# to all APIs. Access drivers can place restrictions
# on this. By default the 'nop' driver is enabled,
# meaning no access control checks are done once a
# client has authenticated with libvirtd
#
#access_drivers = [ "polkit" ]

#################################################################
#
# TLS x509 certificate configuration
#

# Use of TLS requires that x509 certificates be issued. The default locations
# for the certificate files is as follows:
#
#   /opt/homebrew/etc/pki/CA/cacert.pem - The CA master certificate
#   /opt/homebrew/etc/pki/libvirt/servercert.pem - The server certificate signed by cacert.pem
#   /opt/homebrew/etc/pki/libvirt/private/serverkey.pem - The server private key
#
# It is possible to override the default locations by altering the 'key_file',
# 'cert_file', and 'ca_file' values and uncommenting them below.
#
# NB, overriding the default of one location requires uncommenting and
# possibly additionally overriding the other settings.
#

# Override the default server key file path
#
#key_file = "/opt/homebrew/etc/pki/libvirt/private/serverkey.pem"

# Override the default server certificate file path
#
#cert_file = "/opt/homebrew/etc/pki/libvirt/servercert.pem"

# Override the default CA certificate path
#
#ca_file = "/opt/homebrew/etc/pki/CA/cacert.pem"

# Specify a certificate revocation list.
#
# Defaults to not using a CRL, uncomment to enable it
#crl_file = "/opt/homebrew/etc/pki/CA/crl.pem"

#################################################################
#
# Authorization controls
#

# Flag to disable verification of our own server certificates
#
# When libvirtd starts it performs some sanity checks against
# its own certificates.
#
# Default is to always run sanity checks. Uncommenting this
# will disable sanity checks which is not a good idea
#tls_no_sanity_certificate = 1

# Flag to disable verification of client certificates
#
# Client certificate verification is the primary authentication mechanism.
# Any client which does not present a certificate signed by the CA
# will be rejected.
#
# Default is to always verify. Uncommenting this will disable
# verification.
#tls_no_verify_certificate = 1

# An access control list of allowed x509 Distinguished Names
# This list may contain wildcards such as
#
#    "C=GB,ST=London,L=London,O=Red Hat,CN=*"
#
# Any * matches any number of consecutive spaces, like a simplified glob(7).
#
# The format of the DN for a particular certificate can be queried
# using:
#
#    virt-pki-query-dn clientcert.pem
#
# NB If this is an empty list, no client can connect, so comment out
# entirely rather than using empty list to disable these checks
#
# By default, no DN's are checked
#tls_allowed_dn_list = ["DN1", "DN2"]

# Override the compile time default TLS priority string. The
# default is usually "NORMAL" unless overridden at build time.
# Only set this is it is desired for libvirt to deviate from
# the global default settings.
#
#tls_priority="NORMAL"

# An access control list of allowed SASL usernames. The format for username
# depends on the SASL authentication mechanism. Kerberos usernames
# look like username@REALM
#
# This list may contain wildcards such as
#
#    "*@EXAMPLE.COM"
#
# See the g_pattern_match function for the format of the wildcards.
#
# https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html
#
# NB If this is an empty list, no client can connect, so comment out
# entirely rather than using empty list to disable these checks
#
# By default, no Username's are checked
#sasl_allowed_username_list = ["joe@EXAMPLE.COM", "fred@EXAMPLE.COM" ]

#################################################################
#
# Processing controls
#

# The maximum number of concurrent client connections to allow
# over all sockets combined.
#max_clients = 5000

# The maximum length of queue of connections waiting to be
# accepted by the daemon. Note, that some protocols supporting
# retransmission may obey this so that a later reattempt at
# connection succeeds.
#max_queued_clients = 1000

# The maximum length of queue of accepted but not yet
# authenticated clients. The default value is 20. Set this to
# zero to turn this feature off.
#max_anonymous_clients = 20

# The minimum limit sets the number of workers to start up
# initially. If the number of active clients exceeds this,
# then more threads are spawned, up to max_workers limit.
# Typically you'd want max_workers to equal maximum number
# of clients allowed
#min_workers = 5
#max_workers = 20

# The number of priority workers. If all workers from above
# pool are stuck, some calls marked as high priority
# (notably domainDestroy) can be executed in this pool.
#prio_workers = 5

# Limit on concurrent requests from a single client
# connection. To avoid one client monopolizing the server
# this should be a small fraction of the global max_workers
# parameter.
#max_client_requests = 5

# Same processing controls, but this time for the admin interface.
# For description of each option, be so kind to scroll few lines
# upwards.

#admin_min_workers = 1
#admin_max_workers = 5
#admin_max_clients = 5
#admin_max_queued_clients = 5
#admin_max_client_requests = 5

#################################################################
#
# Logging controls
#

# Logging level: 4 errors, 3 warnings, 2 information, 1 debug
# basically 1 will log everything possible
#
# WARNING: USE OF THIS IS STRONGLY DISCOURAGED.
#
# WARNING: It outputs too much information to practically read.
# WARNING: The "log_filters" setting is recommended instead.
#
# WARNING: Journald applies rate limiting of messages and so libvirt
# WARNING: will limit "log_level" to only allow values 3 or 4 if
# WARNING: journald is the current output.
#
# WARNING: USE OF THIS IS STRONGLY DISCOURAGED.
#log_level = 3

# Logging filters:
# A filter allows to select a different logging level for a given category
# of logs. The format for a filter is:
#
#    level:match
#
# where 'match' is a string which is matched against the category
# given in the VIR_LOG_INIT() at the top of each libvirt source
# file, e.g., "remote", "qemu", or "util.json". The 'match' in the
# filter matches using shell wildcard syntax (see 'man glob(7)').
# The 'match' is always treated as a substring match. IOW a match
# string 'foo' is equivalent to '*foo*'.
#
# 'level' is the minimal level where matching messages should
#  be logged:
#
#    1: DEBUG
#    2: INFO
#    3: WARNING
#    4: ERROR
#
# Multiple filters can be defined in a single @log_filters, they just need
# to be separated by spaces. Note that libvirt performs "first" match, i.e.
# if there are concurrent filters, the first one that matches will be applied,
# given the order in @log_filters.
#
# A typical need is to capture information from a hypervisor driver,
# public API entrypoints and some of the utility code. Some utility
# code is very verbose and is generally not desired. Taking the QEMU
# hypervisor as an example, a suitable filter string for debugging
# might be to turn off object, json & event logging, but enable the
# rest of the util code:
#
#log_filters="1:qemu 1:libvirt 4:object 4:json 4:event 1:util"

# Logging outputs:
# An output is one of the places to save logging information
# The format for an output can be:
#    level:stderr
#      output goes to stderr
#    level:syslog:name
#      use syslog for the output and use the given name as the ident
#    level:file:file_path
#      output to a file, with the given filepath
#    level:journald
#      output to journald logging system
# In all cases 'level' is the minimal priority, acting as a filter
#    1: DEBUG
#    2: INFO
#    3: WARNING
#    4: ERROR
#
# Multiple outputs can be defined, they just need to be separated by spaces.
# e.g. to log all warnings and errors to syslog under the libvirtd ident:
#log_outputs="3:syslog:libvirtd"

##################################################################
#
# Auditing
#
# This setting allows usage of the auditing subsystem to be altered:
#
#   audit_level == 0  -> disable all auditing
#   audit_level == 1  -> enable auditing, only if enabled on host (default)
#   audit_level == 2  -> enable auditing, and exit if disabled on host
#
#audit_level = 2
#
# If set to 1, then audit messages will also be sent
# via libvirt logging infrastructure. Defaults to 0
#
#audit_logging = 1

###################################################################
# UUID of the host:
# Host UUID is read from one of the sources specified in host_uuid_source.
#
# - 'smbios': fetch the UUID from 'dmidecode -s system-uuid'
# - 'machine-id': fetch the UUID from /etc/machine-id
#
# The host_uuid_source default is 'smbios'. If 'dmidecode' does not provide
# a valid UUID a temporary UUID will be generated.
#
# Another option is to specify host UUID in host_uuid.
#
# Keep the format of the example UUID below. UUID must not have all digits
# be the same.

# NB This default all-zeros UUID will not work. Replace
# it with the output of the 'uuidgen' command and then
# uncomment this entry
#host_uuid = "00000000-0000-0000-0000-000000000000"
#host_uuid_source = "smbios"

###################################################################
# Keepalive protocol:
# This allows libvirtd to detect broken client connections or even
# dead clients.  A keepalive message is sent to a client after
# keepalive_interval seconds of inactivity to check if the client is
# still responding; keepalive_count is a maximum number of keepalive
# messages that are allowed to be sent to the client without getting
# any response before the connection is considered broken.  In other
# words, the connection is automatically closed approximately after
# keepalive_interval * (keepalive_count + 1) seconds since the last
# message received from the client.  If keepalive_interval is set to
# -1, libvirtd will never send keepalive requests; however clients
# can still send them and the daemon will send responses.  When
# keepalive_count is set to 0, connections will be automatically
# closed after keepalive_interval seconds of inactivity without
# sending any keepalive messages.
#
#keepalive_interval = 5
#keepalive_count = 5

#
# These configuration options are no longer used.  There is no way to
# restrict such clients from connecting since they first need to
# connect in order to ask for keepalive.
#
#keepalive_required = 1
#admin_keepalive_required = 1

# Keepalive settings for the admin interface
#admin_keepalive_interval = 5
#admin_keepalive_count = 5

###################################################################
# Open vSwitch:
# This allows to specify a timeout for openvswitch calls made by
# libvirt. The ovs-vsctl utility is used for the configuration and
# its timeout option is set by default to 5 seconds to avoid
# potential infinite waits blocking libvirt.
#
#

Now, to make sure that was a privilege error, I ran:

qemu-system-aarch64 -netdev vmnet-shared,id=net0 -machine virt-2.10

which reproduces the error, but:

sudo qemu-system-aarch64 -netdev vmnet-shared,id=net0 -machine virt-2.10

opens a qemu window and I got:

qemu-system-aarch64: warning: netdev net0 has no peer

alright, how could I fix libvirt on Mac OS, installed via homebrew?

$ brew info libvirt                               1
==> libvirt: stable 8.10.0 (bottled), HEAD
C virtualization API
https://libvirt.org/
/opt/homebrew/Cellar/libvirt/8.10.0 (587 files, 40.8MB) *
  Poured from bottle on 2023-01-11 at 19:20:38
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/libvirt.rb
License: LGPL-2.1-or-later and GPL-2.0-or-later
==> Dependencies
Build: docutils ✘, meson ✘, ninja ✘, perl ✘, pkg-config ✔, python@3.11 ✔, rpcgen ✘
Required: gettext ✔, glib ✔, gnu-sed ✔, gnutls ✔, grep ✔, libgcrypt ✔, libiscsi ✔, libssh2 ✔, yajl ✔
==> Options
--HEAD
    Install HEAD version
==> Caveats
To restart libvirt after an upgrade:
  brew services restart libvirt
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/libvirt/sbin/libvirtd -f /opt/homebrew/etc/libvirt/libvirtd.conf
==> Analytics
install: 4,452 (30 days), 18,333 (90 days), 69,415 (365 days)
install-on-request: 3,222 (30 days), 13,494 (90 days), 52,022 (365 days)
build-error: 4 (30 days)

Update

Maybe I've found the source of the problem here, if anyone could confirm


问:
Lowest storage way to create a domain branch with clean history?
How can I create a new domain branch without duplicating revision history?  By domain branch, I mean something like "mac", "windows", "serialization", configuration, or another domain of the application — larger than any feature, but smaller than the application proper.  Some argue feature branches may be an anti-pattern.  Regardless, it's useful to logically group feature revisions in a domain branch.  How can this be done with a fresh revision history, so that the first commit is just a squash from master?

For "release", it's sufficient to just squash every merge from master, since "release" never merges back to "master".  The other are upstream of master, but must be created from master and have its prior history by default.
I can do it with
git checkout master && git switch --orphan <domain> && git checkout master -- .gitignore && git add . && git commit -m "create new domain branch <domain>" && git push --set-upstream origin <domain> && git merge --squash master -m "merge changes from master to domain branch <domain>" --allow-unrelated-histories && git push
but that doesn't define the initial commit as a squash in terms of master — it's an unrelated history.  That nearly doubles the size of my repo, which is unacceptable once, let alone for multiple domains.  Is there a way to do this without ballooning my repository?


问:
Accessing a dataweave object value via a variable
I am trying to access a value in a Dataweave object via a variable whose value equals the key. So, if

```<code>var obj = {"a": 2}
var x = "a"
</code>```

then I want something like obj.x to return 2.

obj.x, obj.(x) don't work. I thought accessing the value via the key's index might work using something like obj[(keysOf(obj) find "a")]. But that didn't work either for reasons that I don't understand. Thanks for the help!

Body:
I am trying to access a value in a Dataweave object via a variable whose value equals the key. So, if

var obj = {"a": 2}
var x = "a"

then I want something like obj.x to return 2.

obj.x, obj.(x) don't work. I thought accessing the value via the key's index might work using something like obj[(keysOf(obj) find "a")]. But that didn't work either for reasons that I don't understand. Thanks for the help!


问:
How to implement generics with TypesScript enums

Description

I am storing and checking the key from a keydown event. I have created five enum flags (I had read that enum flags are a way to efficiently store and represent a collection of boolean values) to represent various types of keys on the keyboard:

Alphabet

Modifier

Number

Navigation

Special

I have a Keyboard class that encapsulates all of these enums. The Keyboard class:

has get/set properties for each enum,

has a set(key: string) method, which adds the keyboard key to the appropriate enum, and

has is...(key: enum) methods for each enum (isAlphabet, isNumber), which returns if a given key has been stored as hit in the enum flag

Problem

The Keyboard class is anything but DRY. Code is repeated for every enum. I have tried to figure out how to make the solution more generic, but am having issues using generic syntax with enums.

Question: Any ideas for how to make this code less repetitive?

Code

Enums

```<code>export enum modifierKeys {
    none = 0,
    shift = 1 << 0,
    control = 1 << 1,
    alt = 1 << 2
}

export enum alphabetKeys {
    none = 0,
    a = 1 << 0,
    b = 1 << 1,
    c = 1 << 2,
    d = 1 << 3,
    e = 1 << 4,
    f = 1 << 5,
    g = 1 << 6,
    h = 1 << 7,
    i = 1 << 8,
    j = 1 << 9,
    k = 1 << 10,
    l = 1 << 11,
    m = 1 << 12,
    n = 1 << 13,
    o = 1 << 14,
    p = 1 << 15,
    q = 1 << 16,
    r = 1 << 17,
    s = 1 << 18,
    t = 1 << 19,
    u = 1 << 20,
    v = 1 << 21,
    w = 1 << 22,
    x = 1 << 23,
    y = 1 << 24,
    z = 1 << 25
}

export enum numberKeys {
    none = 0,
    zero = 1 << 0,
    one = 1 << 1,
    two = 1 << 2,
    three = 1 << 3,
    four = 1 << 4,
    five = 1 << 5,
    six = 1 << 6,
    seven = 1 << 7,
    eight = 1 << 8,
    nine = 1 << 9
}

export enum specialKeys {
    none = 0,
    space = 1 << 0,
    enter = 1 << 1,
    backspace = 1 << 2,
    escape = 1 << 3,
    delete = 1 << 4
}

export enum navigationKeys {
    none = 0,
    arrowup = 1 << 0,
    arrowright = 1 << 1,
    arrowdown = 1 << 2,
    arrowleft = 1 << 3
}

export enum keyAlias {
    space = ' ',
    zero = '0',
    one = '1',
    two = '2',
    three = '3',
    four = '4',
    five = '5',
    six = '6',
    seven = '7',
    eight = '8',
    nine = '9'
}
</code>```

Keyboard Class

```<code>export class Keyboard {
    private _modifier: modifierKeys;
    private _special: specialKeys;
    private _navigation: navigationKeys;
    private _alphabet: alphabetKeys;
    private _number: numberKeys;

    public constructor() {
        this.reset();
    }

    public get modifier(): modifierKeys {
        return this._modifier;
    }

    public set modifier(value: modifierKeys) {
        this._modifier = value;
    }

    public get special(): specialKeys {
        return this._special;
    }

    public set special(value: specialKeys) {
        this._special = value;
    }

    public get navigation(): navigationKeys {
        return this._navigation;
    }

    public set navigation(value: navigationKeys) {
        this._navigation = value;
    }

    public get alphabet(): alphabetKeys {
        return this._alphabet;
    }

    public set alphabet(value: alphabetKeys) {
        this._alphabet = value;
    }

    public get number(): numberKeys {
        return this._number;
    }

    public set number(value: numberKeys) {
        this._number = value;
    }

    public reset(): void {
        this._modifier = modifierKeys.none;
        this._special = specialKeys.none;
        this._navigation = navigationKeys.none;
        this._alphabet = alphabetKeys.none;
        this._number = numberKeys.none
    }

    public set(key: string): void {
        // If key matches value of 'keyAlias', set key equal to key of 'keyAlias'
        Object.entries(keyAlias).find(([k, v]) => (key == v) ? key = k : false);

        // Set key
        switch(true) {

            case Object.keys(alphabetKeys).includes(key):
                this._alphabet |= alphabetKeys[key as keyof typeof alphabetKeys];
                break;

            case Object.keys(numberKeys).includes(key):
                this._number |= numberKeys[key as keyof typeof numberKeys];
                break;

            case Object.keys(navigationKeys).includes(key):
                this._navigation |= navigationKeys[key as keyof typeof navigationKeys];
                break;

            case Object.keys(modifierKeys).includes(key):
                this._modifier |= modifierKeys[key as keyof typeof modifierKeys];
                break;

            case Object.keys(specialKeys).includes(key):
                this._special |= specialKeys[key as keyof typeof specialKeys];
                break;
        }
    }

    public isAlphabet(key: alphabetKeys): boolean {
        return ((this._alphabet & key) == key);
    }

    public isNumber(key: numberKeys): boolean {
        return ((this._number & key) == key);
    }

    public isSpecial(key: specialKeys): boolean {
        return ((this._special & key) == key);
    }

    public isModifier(key: modifierKeys): boolean {
        return ((this._modifier & key) == key);
    }

    public isNavigation(key: navigationKeys): boolean {
        return ((this._navigation & key) == key);
    }

}
</code>```

Update

Based on the comments, it appeared enum flags were not the best way to store keyboard key state. Instead, I made:

an enum called KeyType, which specifies the types of keys,

an enum called Keys, which stores the keyboard keys,

a 2D array of KeyType and Keys called KeyMap

a generic interface called IFlag<T, V>, which encapsulates properties for type, value and flag, and

a generic class called FlagContainer<T, V>, which has an array of IFlag<T, V>'s that it operates over

This way each keyboard key is stored in an IFlag<T, V> object rather than an enum flag, and the FlagContainer<T, V> can be used for more than keyboard keys.

Code

Helper Enums & Array

```<code>export enum KeyType {
    alphabet,
    modifier,
    navigation,
    number,
    special
}

export enum Keys {
    shift = 'shift',
    control = 'control',
    delete = 'delete',
    alt = 'alt',
    a = 'a',
    b = 'b',
    c = 'c',
    d = 'd',
    e = 'e',
    f = 'f',
    g = 'g',
    h = 'h',
    i = 'i',
    j = 'j',
    k = 'k',
    l = 'l',
    m = 'm',
    n = 'n',
    o = 'o',
    p = 'p',
    q = 'q',
    r = 'r',
    s = 's',
    t = 't',
    u = 'u',
    v = 'v',
    w = 'w',
    x = 'x',
    y = 'y',
    z = 'z',
    zero = '0',
    one = '1',
    two = '2',
    three = '3',
    four = '4',
    five = '5',
    six = '6',
    seven = '7',
    eight = '8',
    nine = '9',
    space = ' ',
    enter = 'enter',
    backspace = 'backspace',
    escape = 'escape',
    arrowup = 'arrowup',
    arrowright = 'arrowright',
    arrowdown = 'arrowdown',
    arrowleft = 'arrowleft'
}

const KeyMap: [KeyType, Keys][] = [
    [KeyType.alphabet, Keys.a],
    [KeyType.alphabet, Keys.b],
    [KeyType.alphabet, Keys.c],
    [KeyType.alphabet, Keys.d],
    [KeyType.alphabet, Keys.e],
    [KeyType.alphabet, Keys.f],
    [KeyType.alphabet, Keys.g],
    [KeyType.alphabet, Keys.h],
    [KeyType.alphabet, Keys.i],
    [KeyType.alphabet, Keys.j],
    [KeyType.alphabet, Keys.k],
    [KeyType.alphabet, Keys.l],
    [KeyType.alphabet, Keys.m],
    [KeyType.alphabet, Keys.n],
    [KeyType.alphabet, Keys.o],
    [KeyType.alphabet, Keys.p],
    [KeyType.alphabet, Keys.q],
    [KeyType.alphabet, Keys.r],
    [KeyType.alphabet, Keys.s],
    [KeyType.alphabet, Keys.t],
    [KeyType.alphabet, Keys.u],
    [KeyType.alphabet, Keys.v],
    [KeyType.alphabet, Keys.w],
    [KeyType.alphabet, Keys.x],
    [KeyType.alphabet, Keys.y],
    [KeyType.alphabet, Keys.z],
    [KeyType.modifier, Keys.alt],
    [KeyType.modifier, Keys.control],
    [KeyType.modifier, Keys.shift],
    [KeyType.navigation, Keys.arrowup],
    [KeyType.navigation, Keys.arrowright],
    [KeyType.navigation, Keys.arrowdown],
    [KeyType.navigation, Keys.arrowleft],
    [KeyType.number, Keys.zero],
    [KeyType.number, Keys.one],
    [KeyType.number, Keys.two],
    [KeyType.number, Keys.three],
    [KeyType.number, Keys.four],
    [KeyType.number, Keys.five],
    [KeyType.number, Keys.six],
    [KeyType.number, Keys.seven],
    [KeyType.number, Keys.eight],
    [KeyType.number, Keys.nine],
    [KeyType.special, Keys.space],
    [KeyType.special, Keys.enter],
    [KeyType.special, Keys.backspace],
    [KeyType.special, Keys.escape],
    [KeyType.special, Keys.delete],
];
</code>```

Generic Interface / Class

```<code>export interface IFlag<T, V> {
    type: Type;
    value: Value;
    flag: boolean;
}

export class FlagContainer<T, V> {
    private readonly _flag: IFlag<T, V>[];

    public constructor(map: [T, V][]) {
        this._flag = [];

        map.forEach(m => {
            this._flag.push(
                {
                    type: m[0],
                    value: m[1],
                    flag: false
                });
            }
        );
    }

    public clear(): void {
        this._flag.forEach(f => f.flag = false);
    }

    public flagged(value: V): boolean {
        return this._flag.some(f => f.value == value && f.flag == true);
    }

    public flag(value: V): void {
        this._flag.forEach(f => {
            if(f.value == value) f.flag = true
        });
    }

    public any(type: T): boolean {
        return this._flag.some(f => f.type == type && f.flag == true);
    }
}
</code>```

And now the Keyboard object is simplified:

```<code>Class SomeParentClass {
    ...
    private readonly _keyboard: FlagContainer<KeyType, Keys>;
    ...
}
</code>```

I wouldn't say this answers the original question, but I would say this question is closed.

Body:
Description

I am storing and checking the key from a keydown event. I have created five enum flags (I had read that enum flags are a way to efficiently store and represent a collection of boolean values) to represent various types of keys on the keyboard:

Alphabet

Modifier

Number

Navigation

Special

I have a Keyboard class that encapsulates all of these enums. The Keyboard class:

has get/set properties for each enum,

has a set(key: string) method, which adds the keyboard key to the appropriate enum, and

has is...(key: enum) methods for each enum (isAlphabet, isNumber), which returns if a given key has been stored as hit in the enum flag

Problem

The Keyboard class is anything but DRY. Code is repeated for every enum. I have tried to figure out how to make the solution more generic, but am having issues using generic syntax with enums.

Question: Any ideas for how to make this code less repetitive?

Code

Enums

export enum modifierKeys {
    none = 0,
    shift = 1 << 0,
    control = 1 << 1,
    alt = 1 << 2
}

export enum alphabetKeys {
    none = 0,
    a = 1 << 0,
    b = 1 << 1,
    c = 1 << 2,
    d = 1 << 3,
    e = 1 << 4,
    f = 1 << 5,
    g = 1 << 6,
    h = 1 << 7,
    i = 1 << 8,
    j = 1 << 9,
    k = 1 << 10,
    l = 1 << 11,
    m = 1 << 12,
    n = 1 << 13,
    o = 1 << 14,
    p = 1 << 15,
    q = 1 << 16,
    r = 1 << 17,
    s = 1 << 18,
    t = 1 << 19,
    u = 1 << 20,
    v = 1 << 21,
    w = 1 << 22,
    x = 1 << 23,
    y = 1 << 24,
    z = 1 << 25
}

export enum numberKeys {
    none = 0,
    zero = 1 << 0,
    one = 1 << 1,
    two = 1 << 2,
    three = 1 << 3,
    four = 1 << 4,
    five = 1 << 5,
    six = 1 << 6,
    seven = 1 << 7,
    eight = 1 << 8,
    nine = 1 << 9
}

export enum specialKeys {
    none = 0,
    space = 1 << 0,
    enter = 1 << 1,
    backspace = 1 << 2,
    escape = 1 << 3,
    delete = 1 << 4
}

export enum navigationKeys {
    none = 0,
    arrowup = 1 << 0,
    arrowright = 1 << 1,
    arrowdown = 1 << 2,
    arrowleft = 1 << 3
}

export enum keyAlias {
    space = ' ',
    zero = '0',
    one = '1',
    two = '2',
    three = '3',
    four = '4',
    five = '5',
    six = '6',
    seven = '7',
    eight = '8',
    nine = '9'
}

Keyboard Class

export class Keyboard {
    private _modifier: modifierKeys;
    private _special: specialKeys;
    private _navigation: navigationKeys;
    private _alphabet: alphabetKeys;
    private _number: numberKeys;

    public constructor() {
        this.reset();
    }

    public get modifier(): modifierKeys {
        return this._modifier;
    }

    public set modifier(value: modifierKeys) {
        this._modifier = value;
    }

    public get special(): specialKeys {
        return this._special;
    }

    public set special(value: specialKeys) {
        this._special = value;
    }

    public get navigation(): navigationKeys {
        return this._navigation;
    }

    public set navigation(value: navigationKeys) {
        this._navigation = value;
    }

    public get alphabet(): alphabetKeys {
        return this._alphabet;
    }

    public set alphabet(value: alphabetKeys) {
        this._alphabet = value;
    }

    public get number(): numberKeys {
        return this._number;
    }

    public set number(value: numberKeys) {
        this._number = value;
    }

    public reset(): void {
        this._modifier = modifierKeys.none;
        this._special = specialKeys.none;
        this._navigation = navigationKeys.none;
        this._alphabet = alphabetKeys.none;
        this._number = numberKeys.none
    }

    public set(key: string): void {
        // If key matches value of 'keyAlias', set key equal to key of 'keyAlias'
        Object.entries(keyAlias).find(([k, v]) => (key == v) ? key = k : false);

        // Set key
        switch(true) {

            case Object.keys(alphabetKeys).includes(key):
                this._alphabet |= alphabetKeys[key as keyof typeof alphabetKeys];
                break;

            case Object.keys(numberKeys).includes(key):
                this._number |= numberKeys[key as keyof typeof numberKeys];
                break;

            case Object.keys(navigationKeys).includes(key):
                this._navigation |= navigationKeys[key as keyof typeof navigationKeys];
                break;

            case Object.keys(modifierKeys).includes(key):
                this._modifier |= modifierKeys[key as keyof typeof modifierKeys];
                break;

            case Object.keys(specialKeys).includes(key):
                this._special |= specialKeys[key as keyof typeof specialKeys];
                break;
        }
    }

    public isAlphabet(key: alphabetKeys): boolean {
        return ((this._alphabet & key) == key);
    }

    public isNumber(key: numberKeys): boolean {
        return ((this._number & key) == key);
    }

    public isSpecial(key: specialKeys): boolean {
        return ((this._special & key) == key);
    }

    public isModifier(key: modifierKeys): boolean {
        return ((this._modifier & key) == key);
    }

    public isNavigation(key: navigationKeys): boolean {
        return ((this._navigation & key) == key);
    }

}

Update

Based on the comments, it appeared enum flags were not the best way to store keyboard key state. Instead, I made:

an enum called KeyType, which specifies the types of keys,

an enum called Keys, which stores the keyboard keys,

a 2D array of KeyType and Keys called KeyMap

a generic interface called IFlag<T, V>, which encapsulates properties for type, value and flag, and

a generic class called FlagContainer<T, V>, which has an array of IFlag<T, V>'s that it operates over

This way each keyboard key is stored in an IFlag<T, V> object rather than an enum flag, and the FlagContainer<T, V> can be used for more than keyboard keys.

Code

Helper Enums & Array

export enum KeyType {
    alphabet,
    modifier,
    navigation,
    number,
    special
}

export enum Keys {
    shift = 'shift',
    control = 'control',
    delete = 'delete',
    alt = 'alt',
    a = 'a',
    b = 'b',
    c = 'c',
    d = 'd',
    e = 'e',
    f = 'f',
    g = 'g',
    h = 'h',
    i = 'i',
    j = 'j',
    k = 'k',
    l = 'l',
    m = 'm',
    n = 'n',
    o = 'o',
    p = 'p',
    q = 'q',
    r = 'r',
    s = 's',
    t = 't',
    u = 'u',
    v = 'v',
    w = 'w',
    x = 'x',
    y = 'y',
    z = 'z',
    zero = '0',
    one = '1',
    two = '2',
    three = '3',
    four = '4',
    five = '5',
    six = '6',
    seven = '7',
    eight = '8',
    nine = '9',
    space = ' ',
    enter = 'enter',
    backspace = 'backspace',
    escape = 'escape',
    arrowup = 'arrowup',
    arrowright = 'arrowright',
    arrowdown = 'arrowdown',
    arrowleft = 'arrowleft'
}

const KeyMap: [KeyType, Keys][] = [
    [KeyType.alphabet, Keys.a],
    [KeyType.alphabet, Keys.b],
    [KeyType.alphabet, Keys.c],
    [KeyType.alphabet, Keys.d],
    [KeyType.alphabet, Keys.e],
    [KeyType.alphabet, Keys.f],
    [KeyType.alphabet, Keys.g],
    [KeyType.alphabet, Keys.h],
    [KeyType.alphabet, Keys.i],
    [KeyType.alphabet, Keys.j],
    [KeyType.alphabet, Keys.k],
    [KeyType.alphabet, Keys.l],
    [KeyType.alphabet, Keys.m],
    [KeyType.alphabet, Keys.n],
    [KeyType.alphabet, Keys.o],
    [KeyType.alphabet, Keys.p],
    [KeyType.alphabet, Keys.q],
    [KeyType.alphabet, Keys.r],
    [KeyType.alphabet, Keys.s],
    [KeyType.alphabet, Keys.t],
    [KeyType.alphabet, Keys.u],
    [KeyType.alphabet, Keys.v],
    [KeyType.alphabet, Keys.w],
    [KeyType.alphabet, Keys.x],
    [KeyType.alphabet, Keys.y],
    [KeyType.alphabet, Keys.z],
    [KeyType.modifier, Keys.alt],
    [KeyType.modifier, Keys.control],
    [KeyType.modifier, Keys.shift],
    [KeyType.navigation, Keys.arrowup],
    [KeyType.navigation, Keys.arrowright],
    [KeyType.navigation, Keys.arrowdown],
    [KeyType.navigation, Keys.arrowleft],
    [KeyType.number, Keys.zero],
    [KeyType.number, Keys.one],
    [KeyType.number, Keys.two],
    [KeyType.number, Keys.three],
    [KeyType.number, Keys.four],
    [KeyType.number, Keys.five],
    [KeyType.number, Keys.six],
    [KeyType.number, Keys.seven],
    [KeyType.number, Keys.eight],
    [KeyType.number, Keys.nine],
    [KeyType.special, Keys.space],
    [KeyType.special, Keys.enter],
    [KeyType.special, Keys.backspace],
    [KeyType.special, Keys.escape],
    [KeyType.special, Keys.delete],
];

Generic Interface / Class

export interface IFlag<T, V> {
    type: Type;
    value: Value;
    flag: boolean;
}

export class FlagContainer<T, V> {
    private readonly _flag: IFlag<T, V>[];

    public constructor(map: [T, V][]) {
        this._flag = [];

        map.forEach(m => {
            this._flag.push(
                {
                    type: m[0],
                    value: m[1],
                    flag: false
                });
            }
        );
    }

    public clear(): void {
        this._flag.forEach(f => f.flag = false);
    }

    public flagged(value: V): boolean {
        return this._flag.some(f => f.value == value && f.flag == true);
    }

    public flag(value: V): void {
        this._flag.forEach(f => {
            if(f.value == value) f.flag = true
        });
    }

    public any(type: T): boolean {
        return this._flag.some(f => f.type == type && f.flag == true);
    }
}

And now the Keyboard object is simplified:

Class SomeParentClass {
    ...
    private readonly _keyboard: FlagContainer<KeyType, Keys>;
    ...
}

I wouldn't say this answers the original question, but I would say this question is closed.