I`m creating my first app,student grades book, and now i have a problem. I have a txt file full of student info(1 student for each line) and i need to link each student with their marks(they are in other file).What way do you suppose to do it? Maybe I need to make a structure of student name and 2d array?
P.S. Sorry for bad english
Here`s what i mean
Student name lastname
// ---------------------------------------------------------
// |Science |1 |2 |3 |4 |5 |6 |7 |8 |9 |10|11|12|13|14|15|
// ---------------------------------------------------------
// |Maths | | | | | | | | | | | | | | | |
// |English | | | | | | | | | | | | | | | |
1,2,3,4 and etc. is student grade index
A suggestion:
public class Student
{
public Student()
{
Marks = new List<StudentMark>();
}
public string Name { get; set; }
public List<StudentMark> Marks { get; set; }
public void Load(string line)
{
string[] parts = line.Split(' ');
Name = parts[0];
//Other properties, if any:
//LastName = parts[1];
}
}
public class StudentMark
{
public float Mark { get; set; }
public string Lesson { get; set; }
}
I am unsure as to how complex your program is, but would it be an option to create a Student object within which you would save all of the student's information including name and average grade? This would then allow you to save other relavant information. Otherwise, yes it would be an option to look into the dictionary class of the c# langugage. http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
Do you have control of the generation of the separate student and score files? If so can you assign a unique id to each student and store both in each file? This would provide the link between the two. You could add the id as a member of #mahmoodvcs' solution. Then add logic to parse the data by id to get the relevant scores for each student.
Related
The access patterns that I'm interested in is the last item for a given exchange and an account name.
+-------------------------------+-------------------------------------------+---------+--------------------------------------------+------------+----------+------------+---------+-----------+----------------+--------------------------------------------------------------------+---------------------------+----------------------------------+--------------+------------------------------+
| PK | SK | Account | Address | AddressTag | Exchange | Instrument | Network | Quantity | TransactionFee | TransactionId | TransferDate | TransferId | TransferType | UpdatedAt |
+-------------------------------+-------------------------------------------+---------+--------------------------------------------+------------+----------+------------+---------+-----------+----------------+--------------------------------------------------------------------+---------------------------+----------------------------------+--------------+------------------------------+
| Exchange#Binance#Account#main | TransferDate#12/17/2022 4:59:12 PM +02:00 | main | 0xF76d3f20bF155681b0b983bFC3ea5fe43A2A6E3c | null | Binance | USDT | ETH | 97.500139 | 3.2 | 0x46d28f7d0e1e5b1d074a65dcfbb9d90b3bcdc7e6fca6b1f1f7abb5ab219feb24 | 2022-12-17T16:59:12+02:00 | 1b56485f6a3446c3b883f4f485039260 | 0 | 2023-01-28T20:19:59.9181573Z |
| Exchange#Binance#Account#main | TransferDate#12/17/2022 5:38:23 PM +02:00 | main | 0xF76d3f20bF155681b0b983bFC3ea5fe43A2A6E3c | null | Binance | USDT | ETH | 3107.4889 | 3.2 | 0xbb2b92030b988a0184ba02e2e754b7a7f0f963c496c4e3473509c6fe6b54a41d | 2022-12-17T17:38:23+02:00 | 4747f6ecc74f4dd8a4b565e0f15bcf79 | 0 | 2023-01-28T20:20:00.4536839Z |
| Exchange#FTX#Account#main | TransferDate#12/17/2021 5:38:23 PM +02:00 | main | 0x476d3f20bF155681b0b983bFC3ea5fe43A2A6E3c | null | FTX | USDT | ETH | 20 | 3.2 | 0xaa2b92030b988a0184ba02e2e754b7a7f0f963c496c4e3473509c6fe6b54a41d | 2021-12-17T17:38:23+02:00 | 4747f6ecc74f4dd8a4b565e0f15bcf79 | 0 | 2023-01-28T20:20:00.5723855Z |
| Exchange#FTX#Account#main | TransferDate#12/19/2022 4:59:12 PM +02:00 | main | 0xc46d3f20bF155681b0b983bFC3ea5fe43A2A6E3c | null | FTX | USDT | ETH | 15 | 3.2 | 0xddd28f7d0e1e5b1d074a65dcfbb9d90b3bcdc7e6fca6b1f1f7abb5ab219feb24 | 2022-12-19T16:59:12+02:00 | 1b56485f6a3446c3b883f4f485039260 | 0 | 2023-01-28T20:20:00.5207119Z |
+-------------------------------+-------------------------------------------+---------+--------------------------------------------+------------+----------+------------+---------+-----------+----------------+--------------------------------------------------------------------+---------------------------+----------------------------------+--------------+------------------------------+
First of all, it seems to be working as expected but as I'm still learning I'm not so sure whether the partition key and the sort key I chose are good enough or not. This is important as "Uneven distribution of data due to the wrong choice of partition key" can cause reading/writing above the limit issues.
There was a similar example in the documentation and what they say about TransactionId being a partition key is as following:
In most cases you won’t use TransactionID for any query purposes, so you lose the ability to use the partition key to perform a fast lookup of data. To expand this reasoning, consider the traditional order history view on an e-commerce site. Normally orders are retrieved by customer ID or Order ID, not a UID such as a transaction ID that was synthetically generated during checkout. It’s better to choose a natural partition key than generate a synthetic one that won’t be used for querying.
Another interesting part of the documentation is about the composite key
Composite sort keys let you define hierarchical (one-to-many) relationships in your data that you can query at any level of the hierarchy
[country]#[region]#[state]#[county]#[city]#[neighborhood]
This would let you make efficient range queries for a list of locations at any one of these levels of aggregation, from country, to a neighborhood, and everything in between.
I'm also interested in the "Get all user transfers by date range" access pattern but I'm not sure how I could achieve it. So here we are.
C# implementation
public async Task<UserTransferDto?> GetLastAsync(string exchange, string account)
{
var queryRequest = new QueryRequest
{
TableName = TableName,
KeyConditionExpression = "#pk = :pk",
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#pk", "PK" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":pk", new AttributeValue { S = $"Exchange#{exchange}#Account#{account}" } }
},
ScanIndexForward = false,
Limit = 1
};
var response = await _dynamoDb.QueryAsync(queryRequest);
if (response.Items.Count == 0)
{
return null;
}
var itemAsDocument = Document.FromAttributeMap(response.Items[0]);
return JsonSerializer.Deserialize<UserTransferDto>(itemAsDocument.ToJson());;
}
public class UserTransferDto
{
[JsonPropertyName("PK")]
public string Pk => $"Exchange#{Exchange}#Account#{Account}";
[JsonPropertyName("SK")]
public string Sk => $"TransferDate#{TransferDate}";
public required string Exchange { get; init; }
public required string Account { get; init; }
public required DateTimeOffset TransferDate { get; init; }
public required string TransferId { get; init; }
public required TransferType TransferType { get; init; }
public required string Instrument { get; init; }
public required string Network { get; init; }
public required decimal Quantity { get; init; }
public required string Address { get; init; }
public string? AddressTag { get; init; }
public decimal? TransactionFee { get; init; }
public string? TransactionId { get; init; }
public DateTime UpdatedAt { get; set; }
}
public enum TransferType
{
Withdraw = 0,
Deposit = 1
}
Sources:
https://youtu.be/HaEPXoXVf2k?t=720
https://youtu.be/HaEPXoXVf2k?t=798
Hierarchical Data Structures as Items https://youtu.be/HaEPXoXVf2k?t=2775
Access Patterns https://youtu.be/HaEPXoXVf2k?t=2903
https://aws.amazon.com/blogs/database/choosing-the-right-dynamodb-partition-key/
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html
Your base table design works well for getting the latest item for a given exchange and account (via a Query with that as the PK and getting the last sortable from the SK), except that you’re using non-sortable human time stamps instead of sortable time stamps. You should use 2023-01-28 12:56:08 and so on so that the times sort right as strings.
For the other query to find the latest across all exchanges and accounts, you can create a GSI which has a singular PK and the times as the SK. Just beware that you’re limited in how many writes per second you can do to the same PK. Above 1,000 write units per second you’ll need to shard it and then do a query for each shard to get the latest per shard and then the latest overall.
This is a pattern described in https://youtu.be/0iGR8GnIItQ
I have an aggregate root such as:
public class Parent
{
public Guid ParentId {get;set;}
public List<Children> {get;set;}
}
public class Children
{
public Guid ChildrenId {get;set;}
public Parent Parent {get;set;}
public string Name {get;set;}
}
I would like to add aditional property for sorting in Children class. It should help me sort Children by the creatinon order.
How can I implement that? The result in database should be like this:
ChildrenId | Name | Parent |ChildNumber
------------------------------------
guid1 | Name1 | 1 | 1
guid2 | Name2 | 1 | 2
guid3 | Name3 | 1 | 3
guid4 | Name1 | 2 | 1
guid5 | Name2 | 2 | 2
guid6 | Name3 | 2 | 3
I have this data available from the database:
|----------------|--------------|----------------|----------------|----------------|----------------|
| entity_name | provider_id | provider_name | product_id | product_name | country_name |
|----------------|--------------|----------------|----------------|----------------|----------------|
| test | 123 | Provider1 | 1 | Product1 | Russia |
|----------------|--------------|----------------|----------------|----------------|----------------|
| test | 123 | Provider1 | 2 | Product2 | Spain |
|----------------|--------------|----------------|----------------|----------------|----------------|
| test | 123 | Provider1 | 3 | Product3 | France |
|----------------|--------------|----------------|----------------|----------------|----------------|
| test | 456 | Provider2 | 3 | Product3 | France |
|----------------|--------------|----------------|----------------|----------------|----------------|
| test | 123 | Provider1 | 4 | Product4 | France |
And I have to map it to this model in C#:
public class EntityModel
{
public string EntityName { get; set; }
public List<ProviderModel> Providers { get; set; }
}
public class ProviderModel
{
public int ProviderID { get; set; }
public string ProviderName { get; set; }
public List<ProductModel> Products { get; set; }
public ProviderModel() { }
}
public class ProductModel
{
public int ProductID { get; set; }
public string ProductName { get; set; }
public string CountryName { get; set; }
public ProductModel() { }
}
So basically I have to group by providers, for every provider I have to show the products:
{
"entityName": "string",
"providers": [
{
"ProviderID": 0,
"ProviderName": "string",
"products": [
{
"productId": 0,
"productName": "string",
"countryName": "string"
}
]
}
]
}
The sp that returns the data is like this:
SELECT DISTINCT
e.entity_name
,pro.provider_id
,pro.provider_name
,p.product_id
,p.product_name
,pc.country_name
FROM provider_product_table ppt
INNER JOIN product p ON ppt.product_id = p.product_id
INNER JOIN product_parent pp on pp.product_parent_id=p.product_parent_id
INNER JOIN provider pro ON pro.provider_id = ppt.provider_id
INNER JOIN product_country pc on pc.product_id=p.product_id
INNER JOIN entity e on e.product_parent_id=pp.product_parent_id
WHERE p.product_parent_id = #product_parent_id
ORDER BY p.product_id ASC
I tried a lot of groupBy versions but I get stuck at mapping the second list, the products one.
How can I achieve this? Thank you !
let's start with saying that your database is not well-structured or not created for your need, it will be more than good if you try to seprate your data into three table (entity,provider,product) with relationship between entity and provider , and relationship between your provider and the product table.
however, maybe you are developing new feature that it was not thinking at first to make your code or even your database more extensible.
in this case i need to see your group query request (the groupby ) that you created already.
meanwhile i can imagine your need, so you have several solution.
the first one is what are you trying to do , create several query that fill your classes ,i can also imagine with Redundancy, that because there are some id who are unfortunately duplicated due to your database structure, in this case you need to use DISTINCT or INTERSECT (even if its not your need here ) .
seconds one you can deal with temporary table using the keyword INTO#tmpTable if you are using sqlserver, so basically is to crate a new tables in memory to perform your query ( those tables is what i propose above ).
try to edit your question with those query you describe.
I have a SQL Server four tables 'mapping' table MappingACVP as:
Author_ID | CoAuthor_ID | Venue_ID | Paper_ID | Year
----------------------------------------------------
677 | 42700 | 64309 | 812229 | 2005
677 | 42700 | 64309 | 812486 | 2005
677 | 42700 | 64309 | 818273 | 2005
677 | 42700 | 65182 | 812229 | 2005
... | ... | ... | ... | ...
... | ... | ... | ... | ...
By using Entity Framework, I got auto-generated code for all four tables included in Entity Framework Model i.e. Authors.cs, CoAuthors_New.cs, Venues_New.cs and Papers_New.cs as well, whereas tables other than Authors all have Author_ID as foreign key as a relationship.
The auto-generated code for class Authors.cs is as:
public partial class Authors
{
public Authors()
{
this.CoAuthors_New = new HashSet<CoAuthors_New>();
this.Papers_New = new HashSet<Papers_New>();
this.Venues_New = new HashSet<Venues_New>();
}
public int id { get; set; }
public int Author_ID { get; set; }
public string Author_Name { get; set; }
public virtual ICollection<CoAuthors_New> CoAuthors_New { get; set; }
public virtual ICollection<Papers_New> Papers_New { get; set; }
public virtual ICollection<Venues_New> Venues_New { get; set; }
}
Now if I want to declare a list as:
List<Authors> _eAthors = new List<Authors>();
and want to fetch values for filling this list from database (using MappingACVP table), whereas there is no Year property in Authors.cs class. So,
How will I fill eAuthors list from database?
How to create an instance of an object with a navigation property?
In my application, I am using two classes to represent an object of Fruit and an object of Color as defined below.
public class Fruit
{
public Fruit(int fruitId, string name, Color color)
{
FruitId = fruitId;
Name = name;
Color = color;
}
public int FruitId { get; set; }
public string Name { get; set; }
public Color Color { get; set; }
}
public class Color
{
public Color(int colorId, string name, List<Fruit> fruits)
{
ColorId = colorId;
Name = name;
Fruits = fruits;
}
public int ColorId { get; set; }
public string Name { get; set; }
public List<Fruit> Fruits { get; set; }
}
When creating an instance of Fruit or Color, I get their data from a database which is rather easy, but the problem is, I don't understand how to fill up the data for either the Fruit or the Color's navigation properties...
result = some_query_result_from_database...
Fruit f = new Fruit(result["FruitId"], result["Name"], ???);
Problem:
If I replace the ??? from the above code with the following:
new Color(some_colorId, some_colorName, some_list_of_fruits)
Where can I get the some_list_of_fruits?
Update #1:
The Fruit and Color objects from above represents tables from a database, for this example I named it the same, so Fruit object has a Fruit table counterpart from the database and so does the Color object:
Table definition:
+----------+
| Fruit |
+----------+
| FruitId |
| Name |
| ColorId |
+----------+
|∞
|
|1
+----------+
| Color |
+----------+
| ColorId |
| Name |
+----------+
Table contents:
Fruits
+---------+--------+----------+
| FruitId | Name | ColorId |
+---------+--------+----------+
| 10 | Apple | 70 |
| 20 | Orange | 80 |
| 30 | Grapes | 90 |
+---------+--------+----------+
Colors
+----------+--------+
| ColorId | Name |
+----------+--------+
| 70 | Red |
| 80 | Orange |
| 90 | Violet |
+----------+--------+
Update #2:
I overlooked at SriramSakthivel's comment, I realized SriramSakthivel is also asking how I get the data for my objects. So here it is.
For my Fruit object:
string cs = some_connection_string;
MySqlConnection c = new MySqlConnection(cs);
try
{
c.Open();
string query = select_statement_to_get_fruits_from_db;
...then after that, I use MySqlDataReader to loop through the result to create fruit objects
}
For my Color object, it's just the same steps like the above commands except that on my query, I replaced it with a select statement to retrieve color data from database.
You have circular dependency and you'll not be able to construct complete objects in constructor - you'll have to fill at least one side of circular dependency later.
One option is to build up collections of "fruits" while you are creating them:
Build collection of all colors first but have lists of fruits empty (Dictionary by colorId is probably what you are looking for).
When creating fruit register the fruit in Color's list of fruits:
Sample:
public Fruit(int fruitId, string name, Color color)
{
FruitId = fruitId;
Name = name;
Color = color;
color.Fruits.Add(this);
}
You can also create colors on demand while creating fruit:
public Fruit CreateFruit(int fruitId, string fruitName, int colorId)
{
if (!colorDictionary.ContainsKey(colorId))
{
var name = ...// Somehow get color name for colorID
colorDictionary.Add(colorId,
new Color { ColorId = ColorId, Name = name, List = new List<Fruits>()});
}
return new Fruit(fruitId, fruitName, colorDictionary[colorId];
}