Making a class member array of objects in Python3 - c#

I'm trying to create 3 custom classes in Python:
One for a "Property"
One for a "Building"
One for a "Tenant"
In reality, a property can have multiple buildings on it, and each building can have multiple tenants. So, in trying to code that in Python, I haven't found a clear way to have a class member variable which is an array of objects of the other classes' type. In C# I did it using C# Lists, as follows:
public class Property
{
public string Name { get; set; }
public List<Building> Buildings = new List<Building>();
}
public class Building
{
public string Name { get; set; }
public List<Tenant> Tenants = new List<Tenant>();
}
public class Tenant
{
public string Name { get; set; }
public int SF { get; set; }
public decimal Rent { get; set; }
}
How can I do this in Python? Actually I've been kind of confused in general how to 'declare' class member variables.. it seems like the closest thing to declaring them is setting them to a value for the first time in the __init__ constructor, which feels odd to me. Anyways I'm new to Python so maybe that's just how it's done.
I've read a little bit about how tuples and lists are used in Python, so I'm guessing the solution would have something to do with that, but I'm having trouble figuring it out.
Thanks any help is appreciated

Related

Is sharing base and derived class names a bad practice?

Since people have requested more context, I will try to provide a concrete example of the problem. I am doing some sort of generic ERP system that displays the usage of resources in a diagram. I have some generic classes that are used to model the problem such as Job, Resource, and Operation. Something like this:
public class Job
{
public string ID { get; }
public string Name { get; set; }
public DateTime Arrival { get; }
public Job(string id, DateTime arrival)
{
Arrival = arrival;
ID = id;
}
}
public class Resource
{
public string ID { get; set; }
public string Name { get; set; }
protected Resource(Resource other) => ID = other.ID;
}
public class Operation
{
public string ID { get; }
public string Name { get; set; }
public Job ProcessedJob { get; }
public Resource Processing Resource { get; }
public Operation(string id, Job processedJob, Resource processingResource)
{
ID = id;
ProcessedJob = processedJob;
ProcessingResource = processingResource
}
}
However, the application is generic so this modeling may not be enough for all possible problems. For example, there may be Jobs that have properties such as the maximum time they can take to be processed or resources that have a certain schedule. The thing is that depending on the concrete problem I am modeling these characteristics may be part of the problem or not so expanding each class whenever a new problem case arises doesn't seem a good idea since it will pollute the code.
The obvious solution is inheriting from each base class and having a derived class for each problem case so that includes the desired properties, such as Problem1Job and Problem1Resource. In my opinion, this also gets messy if more problem cases or base classes are added because the total file count increases. An example of this could be (I didn't include constructors for the sake of clarity):
public class Problem1Job : Job
{
public bool ExtraPropertyA {get ; set; }
public string ExtraPropertyB {get ; set; }
public int ExtraPropertyC {get ; set; }
}
public class Problem1Resource : Resource
{
public bool ExtraPropertyA {get ; set; }
public int ExtraPropertyB {get ; set; }
}
Instead of storing all these classes in one folder, I have decided to group all the base classes in one folder called base, with its own namespace, and create a folder for each of the problems with a different namespace. This allows me to create classes that are Job : base.Job and Resource : base.Resource inside the namespace Problem1, thus sharing the name with their base classes but in a different namespace. For me, it is a clean way to organize the files, but I don't know if there is any convention regarding sharing the names between the base and derived classes (given they are in different namespaces) or if it is considered a bad practice/code smell.

Storing query result into a variable

I'm a very beginner of C# and have some troubles with correct understading of generic types. In this example I would like to somehow store a query result into a variable.
The code I showed below is incorrect, because generic type T should specified.
public class Data
{
public IQueryable<T> Results { get; set; }
public Data()
{
var db = new Database();
}
public void Store()
{
Results = db.Products.Select(x => new { x.ProductName, x.Cost });
}
}
Is it possible to do it without declaring a special class for only one use, like this one?
public class ProductView
{
public string ProductName { get; set; }
public int Country { get; set; }
}
...
public IQueryable<ProductView > Results { get; set; }
Also, why dynamic type doesn't suit in this example?
public dynamic Results { get; set; }
There are 3 ways to solve this problem:
1) Create class like ProductView that you mentioned - classical C#6 or older way
2) Use dynamic instead of T like: public IQueryable<dynamic> Results { get; set; } - not recommended, because it increases risk of runtime errors and reduces readability
3) Use tuples (C#7 feature):
public IQueryable<(string, int)> Results { get; set; } // I suppose ProductName is string and Cost is int
public void Store()
{
Results = db.Products.Select(x => (x.ProductName, x.Cost));
}
The problem here is that your Data class appears to know some specific things about T. In the Store method it reads the Products and obtains two specific properties from each item. So it is not actually a generic class that can store any type. It's very specific.
To make it generic you would need to remove the Store method. And then there is not much left. You need to decide what the purpose of Data is. What problem does it exist to solve?

How can I model a template-like entity in DDD?

I am a beginner with DDD and I try to model elegantly in C# the next scenario:
A template that basically has only a name property on it and a list of items that have to be executed in a specific order.
public class Template
{
public string Name { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public string Name { get; set; }
public int Order { get; set; }
}
A type called Profile.
public class Profile
{
public string Name { get; set; }
}
The profile class is intended to say
I am using template A to know what items I have and in what order
If template A changes, then I am using the new version because I don't want to keep a clone of the list template A had.
If I am deleted then the template is not affected in any way
If I am created then I require a template
I can be looked after by my name only
This looks like the aggregate root would be the template, which would have a list of Items and a list of Profiles. But I feel that searching by the name of the profile is requiring me to search all the templates that have a profile with the given name. Somehow, coming from a CRUD background, it seems a high price to pay. Also, the profile is the one that uses the template and having the template know about profiles that use it, seems wrong.
How do you model this? What should be the aggregate root here? Is more than one? How do you perform the search if you want to use it from UI?
Don't. Do not start meta-modeling and over-abstracting when you need to learn DDD. It is a really bad idea, as it will focus your attention on things that have nothing to do with learning DDD, will distract you, and will lead you to making bad decisions.
You need to start with solving concrete problems. Abstractions need to come from the concrete solutions. After you have implemented (at least three of) them, it is time to look at abstractions
Neither Profile or Template can be nested within the other aggregate, they need to exist as separate aggregates. It sounds as though the Profile needs to keep a reference to which Template it is using. Therefore, I'd include a reference to the template by id (Template.Name).
public class Template
{
public string Name { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public string Name { get; set; }
public int Order { get; set; }
}
public class Profile
{
public string Name { get; set; }
public string TemplateName { get; set; }
}

Deserialize object using JSON.NET, but put some properties into a member of the class

I am writing a set of data structures to ingest third-party JSON into (no writing out) using JSON.NET.
I have a case for reading some of the top-level JSON elements into a member object of the object being deserialized into.
My JSON:
{
"Id":1
"Checksum":42
"Name":"adam",
"Hair":true
}
My ideal object structure:
public class EntityHeader
{
int Id { get; set; }
int Checksum { get; set; }
}
public class Entity
{
[HeroicJsonAttribute( "Id", "Checksum" )]
public EntityHeader Header { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
Is there a simple way to achieve this? I will have a number of types which will need this, and I'd hate to have to write a JsonConverter for each.
This question has been asked before, here, but the accepted answer doesn't address the question.
Thanks!
An alternative approach would be to use an EntityHeader field in the Entity class as a backing store for private properties which can be deserialized into:
public class EntityHeader
{
int Id { get; set; }
int Checksum { get; set; }
}
public class Entity
{
private EntityHeader m_Header = new EntityHeader();
public EntityHeader Header { get { return m_Header; } }
[JsonProperty]
private int Id { set { m_Header.Id = value; } }
[JsonProperty]
private int Checksum { set { m_Header.Checksum = value; } }
public string Name { get; set; }
public bool Hair { get; set; }
}
Thus, all the properties in the JSON can be read straight into the Entity object, but consumers of Entity objects have access to a "nicely encapsulated" EntityHeader property.
I haven't tested this, and it may even be kludgey, but it would technically work for me (OP). I am still interested in other answers!
Base on your example you could either; use the adapter pattern:
public class EntityJson
{
int Id { get; set; }
int Checksum { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
// quick/poor example
public class EntityAdapter : IEntity
{
public EntityAdapter(EntityJson model)
{
Header = new Header(); // and populate this objects fields
Name = model.Name; // populate other properties
}
public EntityHeader Header { get; set; }
public string Name { get; set; }
public bool Hair { get; set; }
}
Or abuse the fact that json.net ignores properties not available:
var entity = JsonConvert.Deserialze<Entity>();
var header = JsonConvert.Deserialize<EntityHeader>();
entity.Header = header;
I'm going to go ahead and post this answer which is a little bit too long for a comment, so please take this more as an extended comment than an actual attempt to answer your specific question. And of course, you know your requirements best so this is just my considered opinion :)
With that in mind, my advice is:
Don't do this.
I would instead create a simple DTO class that has a 1-1 relationship to the JSON being received; and I'd put all my validation attributes on the properties of that class.
Once I had deserialised the JSON into this simple DTO, I would then use a mapping layer of some kind (roll your own or use Automapper, etc) to map this DTO into a more meaningful structure such as your Entity class.
My reasoning behind this is because unless your Entity class is itself only a simple DTO (in which case it should be as simple as possible and ideally not be a composite) you are mixing OOP and concerns with data mapping concerns; whilst this in and of itself is not such a bad thing, it only serves to increase the complexity of your code.
Consider for example if your incoming JSON ends up with 30 or 40 properties, and you manage to figure out a way (maybe adapting some of the nice techniques from the other answers) to map it to the Entity class. But what about when something goes wrong - it's going to be much easier to reason about, and therefore debug, a process which you have much more control over; it's also going to be much easier to make special adaptations for odd edge cases where the serialiser behaviour just can't help you out
Granted it's a bit of work to write and maintain these DTOs but not that much - Webtools already does this for you
Reference: At the boundaries, Applications are not Object-Oriented

Help refactor my C# code to be more maintainable and to use best coding practices

I have this C# class structure that I would like to refactor to use best coding standards (use interfaces/abstract classes) so it can be more maintainable and reusable. The code as it is right now isn't awful, but it's not ideal.
I have a series of TableItemGroup classes: AccountTableItemGroup, PendingVoteTableItemGroup, and RequestingVoteTableItemGroup. Each TableItemGrup contains a string SectionName and a List for its corresponding TableItem ...as such:
public class AccountTableItemGroup {
public string SectionName { get; set; }
public List<AccountTableItem> Items
{
get { return this._items; }
set { this._items = value; }
}
public List<AccountTableItem> _items = new List<AccountTableItem>();
public AccountTableItemGroup()
{
}
}
In the future there will be many more TableItemGroups and if they are all the same except for the List part, I don't want to have to copy the code and create a new Group every time and make that small change. I know there must be a better way. I would like to keep using the List<> generics so I don't have to cast anything later though.
The other part are the TableItems. I have AccountTableItem, PendingVoteTableItem, and RequestingVoteTableItem. The TableItems are different from each other, but they each share three common strings -- TitleLabel, DetailLabel, and ImageName. But after that, each TableItem may or may not have additional properties or methods along with it ..as such:
public class AccountTableItem
{
public string TitleLabel { get; set; }
public string DetailLabel { get; set; }
public string ImageName { get; set; }
public bool SwitchSetting { get; set; }
public AccountTableItem()
{
}
}
So my question to all of you is, how do I redefine my class structure to allow for as much reuse of code as possible and to use best coding standards?
I was thinking of having an abstract TableItem class or use an interface for the TableItemGroup? I know that using an interface or an abstract class is best for coding standards, but I don't see how it would cut down on the amount of code I will have?
Thanks a lot for any help.
Abstract away your table item adding necessary fields to the interface or base class:
interface ITableItem // or just a simple or abstract class
{
// common fields go here
}
Then can you make your item group generic with a constraint on generic parameter.
public class ItemGroup<T> where T: ITableItem
{
public string SectionName { get; set; }
public List<T> Items { get; private set; }
public ItemGroup()
{
Items = new List<T>();
}
}
Consider using generics to represent the TableItemGroup container, and make a base class for your TableItem, which you can inherit from for specific types of table item. If you inherit directly from List<T>, then you can treat your item group as a collection without having to use the Items property as in your existing design.
There's not much point in using interfaces for these sorts of types. As they stand they are data classes so have no behavior. If they had behavior, using interfaces would make sense as you would then be able to change implementations and so vary behavior.
public class TableItemGroup<T> : List<T> where T : TableItem
{
public TableItemGroup(string sectionName)
{
SectionName = sectionName;
}
public string SectionName { get; private set; }
}
public class TableItem
{
public string TitleLabel { get; set; }
public string DetailLabel { get; set; }
public string ImageName { get; set; }
}
public class AccountTableItem : TableItem
{
public bool SwitchSetting { get; set; }
}
Now that we have a generic TableItemGroup container, you can re-use this for all TableItem types. Having a base class for TableItem again gives you some re-use.
var items = new TableItemGroup<AccountTableItem>("Accounts");
items.Add(new AccountTableItem { SwitchSetting = true });
Unless you want users to be able to add and remove new lists at will, you should make the setter on the items list protected. Users will still be able to add and remove items, but not create a reference to a new list.

Categories

Resources