So i'm trying to make this console Program where you can add comments and a rating to a certain book. A certain comment can also be upvoted.
Here is my Comment.cs
class Comment
{
#region state
private readonly string name;
private readonly string commentary;
private readonly uint rating;
private uint votes;
#endregion state
#region constructor
public Comment(string name , string commentary, uint rating)
{
this.name = name;
this.commentary = commentary;
this.rating = rating;
this.votes = 0;
}
#endregion
#region properties
public string Name
{
get { return name; }
}
public string Commentary
{
get { return commentary; }
}
public uint Rating
{
get { return rating; }
}
public uint Votes
{
get { return votes; }
private set { votes = value; }
}
#endregion
#region behaviour
public void VoteHelpfull()
{
Votes++;
}
public override string ToString()
{
string[] lines ={
"{0}",
"Rating: {1} - By: {2} voterating: {3}"
};
return string.Format(
string.Join(Environment.NewLine,lines),Commentary,Rating,Name,Votes);
}
#endregion
}
You can add comments to a book by where they are stored in List<Comment> Comments
class Book
{
#region state
private readonly string bookname;
private readonly decimal price;
private List<Comment> comments;
#endregion
#region constructor
public Book(string bookname,decimal price)
{
this.bookname = bookname;
this.price = price;
comments = new List<Comment>();
}
#endregion
#region properties
private List<Comment> Comments
{
get { return comments; }
set { comments = value; }
}
public string Bookname
{
get { return bookname; }
}
public decimal Price
{
get { return price; }
}
#endregion
#region behaviours
public void AddComment(string name, string commentary, uint rating)
{
Comments.Add(new Comment(name, commentary, rating));
}
public override string ToString()
{
string s = string.Format("{0} - {1} euro - {2} comments",Bookname,Price,Comments.Count);
foreach (Comment c in Comments)
{
s += Environment.NewLine;
s += c;
}
return s;
}
I'm trying to Order the list of comments a book has by the votes property of my comment object has but I can't seem to make it work...
Try this:
foreach (Comment c in Comments.OrderBy(c=>c.Votes))
{
.....
}
Related
I am working with delegates and events for the first time and help. When the program runs its supposed to show the text in blue if the gpa has increased from the original and red if it has decreased. I have to use two events IncreaseGpaEvent and DecreaseGpaEvent. Have to have a color variable and is assigned in the ToString(). Any help is greatly appreciated.
public delegate void UpdateGPADelegate(string ConsoleColor);
class Student
{
// Fields
private string studentName;
private double gpa;
public string ConsoleColor;
public event UpdateGPADelegate IncreaseGpaEvent;
public event UpdateGPADelegate DecreaseGpaEvent;
// Properties
public string StudentName { get; set; }
public double GPA
{
get { return gpa; }
set
{
IncreaseGpaEvent += onUpdate;
if (!(value > gpa))
{
gpa = value;
IncreaseGpaEvent("Red");
}
DecreaseGpaEvent += onUpdate;
if(!(value < gpa))
{
gpa = value;
DecreaseGpaEvent("Blue");
}
}
}
public Student(string studentName, double gpa)
{
this.studentName = studentName;
this.gpa = gpa;
}
public void onUpdate(double value)
{
if (value < gpa)
{
ConsoleColor = "Red";
}
if (value > gpa)
{
ConsoleColor = "Blue";
}
}
public override string ToString()
{
string str;
str = string.Format($"Name: {StudentName} GPA: {GPA}");
return str;
}
}
Try This..
public delegate void UpdateGPADelegate(double ConsoleColor);
class Student
{
// Fields
// private string studentName;
private double gpa;
public string ConsoleColor;
public event UpdateGPADelegate IncreaseGpaEvent;
public event UpdateGPADelegate DecreaseGpaEvent;
// Properties
public string StudentName { get; set; }
public double GPA
{
get { return gpa; }
set
{
if (!(value > gpa))
{
IncreaseGpaEvent(value);
gpa = value;
}
if(!(value < gpa))
{
DecreaseGpaEvent(value);
gpa = value;
}
}
}
public Student(string studentName, double gpa)
{
this.studentName = studentName;
this.gpa = gpa;
IncreaseGpaEvent += onUpdate;
DecreaseGpaEvent += onUpdate;
}
public void onUpdate(double value)
{
if (value < gpa)
{
ConsoleColor = "Red";
}
if (value > gpa)
{
ConsoleColor = "Blue";
}
}
public override string ToString()
{
string str;
str = string.Format($"Name: {StudentName} GPA: {GPA} ConsoleColor: {ConsoleColor}");
return str;
}
}
There were somethings wrong with the code which i have fixed like you were assigning value to gpa after that events were raised which never would be greater or smaller and signature of delegate was also wrong.
Create three small classes unrelated by inheritance—classes Building, Car and Bicycle. Write an interface ICarbonFootprint with a GetCarbonFootprint method. Have each of your classes implement that interface, so that its GetCarbonFootprint method calculates an appropriate carbon footprint for that class (check out a few websites that explain how to calculate carbon footprints). Write an app that creates objects of each of the three classes, places references to those objects in List, then iterates through the List, polymorphically invoking each object’s GetCarbonFootprint method. Constructor of Car initialize “gallon of gas”, and the Building constructor will initialize buiding-square-footage.
how to calculate carbon-footprint
One gallon of gas yields 20 pounds of CO2 for a car
Multiply the square footage by 50 for a building
None for a bicycle
My instructor's code:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
static void Main(string[] args)
{
Bicycle bike = new Bicycle();
Building b = new Building();
Car car = new Car();
List<ICarbonFootprint> list = new List<ICarbonFootprint>();
list.Add(bike);
list.Add(b);
list.Add(car);
int totalCarbon = 0;
foreach (var item in list)
{
totalCarbon += item.GetCarbonFootprint();
Console.WriteLine("{0} has a footprint of: {1}", item, item.GetCarbonFootprint());
}
Console.WriteLine("Total footprint is: {0}", totalCarbon);
Console.ReadKey();
}
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
Me integrating my instructor's code (lines 12-23 changed AKA class Program was the only thing changed):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Miller
{
class Program
{
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
list[i].GetCarbonFootprint();
} // end Main
}
public class Bicycle : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 10;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Building : ICarbonFootprint
{
private string _address;
public string Address
{
get { return _address; }
set { _address = value; }
}
public int GetCarbonFootprint()
{
return 2000;
}
public override string ToString()
{
return string.Format("Building");
}
}
public class Car : ICarbonFootprint
{
private string _make;
private string _model;
public string Make
{
get { return _make; }
set { _make = value; }
}
public string Model
{
get { return _model; }
set { _model = value; }
}
public int GetCarbonFootprint()
{
return 1500;
}
public override string ToString()
{
return string.Format("Car");
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
}
So, replacing my code for class Program with my instructor's code, I received the following errors:
Program.cs(51,23,51,41): error CS1729: 'Miller.Building' does not contain a constructor that takes 1 arguments
Program.cs(52,23,52,34): error CS1729: 'Miller.Car' does not contain a constructor that takes 1 arguments
Now, because the last two days before Spring break were cancelled due to the weather (snow), we weren't able to discuss. My code seems to do what the directions ask, but I would like to get my instructor's code for class Program working with my code. Could someone help me with these errors possibly?
There are a few issues with your code.
First up you need to include the constructors to make the code compile.
For Building this would look like:
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
And for Car this would look like:
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
Next, you're not following the rules for calculating the carbon footprint.
They should be:
//Bicycle
public int GetCarbonFootprint()
{
return 0;
}
//Building
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
//Car
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
Finally, your instructor's code doesn't actually display any results. The code in the for loop should be changed to be Console.WriteLine(list[i].GetCarbonFootprint()); if this is a console app.
So, all up the code should look like this:
public static void Main(string[] args)
{
ICarbonFootprint[] list = new ICarbonFootprint[3];
// add elements to list
list[0] = new Bicycle();
list[1] = new Building(2500);
list[2] = new Car(10);
// display carbon footprint of each object
for (int i = 0; i < list.Length; i++)
Console.WriteLine(list[i].GetCarbonFootprint());
}
public class Bicycle : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 0;
}
}
public class Building : ICarbonFootprint
{
private int squareFootage;
public Building(int squareFootage)
{
this.squareFootage = squareFootage;
}
public string Address { get; set; }
public int GetCarbonFootprint()
{
return 50 * squareFootage;
}
}
public class Car : ICarbonFootprint
{
private int gasGallons;
public Car(int gasGallons)
{
this.gasGallons = gasGallons;
}
public string Make { get; set; }
public string Model { get; set; }
public int GetCarbonFootprint()
{
return 20 * gasGallons;
}
}
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
I've opted to short-cut the property definitions rather than implement them with fields.
The output is:
0
125000
200
You should write constructors for Building and Car like next:
public Building(int MyValue)
{
...
}
and your code will work fine.
Suggestion: Car and Bicycle shares properties, and the ICarbonFootprint implementation, so you can create a base class with an abstract method. Also the GetCarbonFootprint from ICarbonFootprint interface must be type of System.Double.
public interface ICarbonFootprint
{
int GetCarbonFootprint();
}
public class Building : ICarbonFootprint
{
public int BuildingSquareFootage { get; set; }
public string Address { get; set; }
public Building(int buildingSquareFootage, string address)
{
BuildingSquareFootage = buildingSquareFootage;
Address = address;
}
public int GetCarbonFootprint()
{
return BuildingSquareFootage * 50;
}
public override string ToString()
{
return string.Format("Building");
}
}
public abstract class CarBicycleBase : ICarbonFootprint
{
public string Make { get; set; }
public string Model { get; set; }
protected CarBicycleBase(string make, string model)
{
Make = make;
Model = model;
}
public abstract int GetCarbonFootprint();
}
public class Bicycle : CarBicycleBase
{
public Bicycle(string make, string model)
: base(make, model) { }
public override int GetCarbonFootprint()
{
return 0;
}
public override string ToString()
{
return string.Format("Bike");
}
}
public class Car : CarBicycleBase
{
public int GallonOfGas { get; set; }
public Car(int gallonOfGas, string make, string model)
: base(make, model)
{
GallonOfGas = gallonOfGas;
}
public override int GetCarbonFootprint()
{
return GallonOfGas * 20;
}
public override string ToString()
{
return string.Format("Car");
}
}
Example:
...
var list = new List<ICarbonFootprint>(3)
{
new Car(10, "...", "..."),
new Bicycle("...", "..."),
new Building(20, "...")
};
foreach (ICarbonFootprint item in list)
item.GetCarbonFootprint();
...
I hope it helps.
I am totally unable to access the outer class attributes inside the inner class ...
even if i make object of outer class,, in inner class*which makes no sense in composition design* .. even then i cant access them ..
is there a way by which i can access these outer class attributes ?
Scenario is that there is some sports car which is constructed only if the customers who want to buy it exists! ..
namespace composition{
public class CustomCar
{
#region Attributes
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
#endregion
#region properties
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
#endregion
#region methods
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string s1, string pno, double c, string s2, double n, double bc)
{
this.Name = s1;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = s2;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
#endregion
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
}
}
There is nothing stopping you having a reference in the CarCustomer to the CustomCar object as well. This would then give you a one to one reference between the object. Were you instaiate this object is up to you in the Constructor of the CustomCar
public CustomCar(arguments)
{
this.Customer.CustomCar = this;
}
Or you could set it in the sets on the property accessors up to you. Try this
public class CustomCar
{
private string name;
private string plateno;
private double cost;
private CarCustomer _customer = new CarCustomer();
public string Name
{
get { return name; }
set { name = value; }
}
public double Cost
{
get { return cost; }
set { cost = value; }
}
public string PlateNo
{
get { return plateno; }
set { plateno = value; }
}
public CarCustomer Customer
{
get { return _customer; }
set { _customer = value; }
}
public CustomCar()
{
Console.WriteLine("I am in custom car");
}
public CustomCar(string name, string pno, double c, string customerName, double n, double bc)
{
this.Name = name;
this.PlateNo = pno;
this.Cost = c;
this.Customer.Name1 = customerName;
this.Customer.Nic1 = n;
this.Customer.BargainCost = bc;
this.Customer.Car = this;
}
public double finalCost()
{
if (this.Customer.BargainCost < 10000)
{
double FinalCost = (this.Cost - this.Customer.BargainCost);
return FinalCost;
}
else
{
return this.Cost;
}
}
public void show()
{
Console.WriteLine(this.name + this.PlateNo + this.Customer.Name1 + this.Customer.Nic1);
}
}
public class CarCustomer
{
private string name1;
private double Nic;
private double bargainCost;
private CustomCar customer;
public double BargainCost
{
get { return bargainCost; }
set { bargainCost = value; }
}
public double Nic1
{
get { return Nic; }
set { Nic = value; }
}
public string Name1
{
get { return name1; }
set { name1 = value; }
}
public CustomCar Car
{
get{return customer;}
set{customer = value;}
}
public CarCustomer()
{
Console.WriteLine("I have a customer");
}
public CarCustomer(string n1, double i1, double bc)
{
this.Name1 = n1;
this.Nic = i1;
this.BargainCost = bc;
}
public void showCustomer()
{
Console.WriteLine("Customer name: " + Name1);
Console.WriteLine("Customer NIC: " + Nic1);
}
}
Of course you can't access them. You've set their protection level to private. In order to get at them from an external resource their protection level has to be in line with the access level needed. In this case you should be able to change the modifier to protected and be able to access them.
However, looking at your class design, I think you would be better served using the automatic getter/setter syntax. You aren't doing anything particularly special in your property definitions, so it would make sense to get rid of the private variables and change your properties to this:
public string Name { get; set; }
public double Cost { get; set; }
public string PlateNo { get; set; }
public CarCustomer Customer { get; set; }
You'll still have public access to the variables through the properties and you won't have all the messiness of the extra variables.
I'm having trouble converting especially the getter and setter.
public class CartItem : IEquatable<CartItem>
{
#region Attributes
public int Quantity { get; set; }
private int _productId;
public int ProductId
{
get { return _productId; }
set
{
_product = null;
_productId = value;
}
}
private Product _product = null;
public Product Prod
{
get
{
if (_product == null)
{
_product = new Product(ProductId);
}
return _product;
}
}
public string Name
{
get { return Prod.ProductName; }
}
public string Description
{
get { return Prod.Description; }
}
public float UnitPrice
{
get { return Prod.UnitPrice; }
}
public float TotalPrice
{
get { return UnitPrice * Quantity; }
}
#endregion
#region Methods
public CartItem(int productId)
{
this.ProductId = productId;
}
public bool Equals(CartItem item)
{
return item.ProductId == this.ProductId;
}
#endregion
}
sample of getters and setters in Java:
public class Employee {
private int empId;
private String name;
private int age;
public Employee(int empId, String name, int age) {
this.empId = empId;
this.name = name;
this.age = age;
}
// getters & setters
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
using your code:
public class Sample {
private int _productId;
public int get_productId() {
return _productId;
}
public void set_productId(int productId) {
_productId = productId;
}
private Product _product = null;
public Product get_product() {
if (_product == null) {
_product = new Product();
}
return _product;
}
public void set_product(Product product) {
_product = product;
}
}
and something more:
public class Product {
String desription;
public String getDesription() {
return desription;
}
public void setDesription(String desription) {
this.desription = desription;
}
}
//this is your hidding delegation getter only in main class (Sample in my samples)
public String getDescription(){
return _product.getDesription();
}
Java getters and setters aren't as easy to use as C#'s. In Java, every getter and setter has to be explicitly defined, rather than using the shorthand you have there.
For example, for your code "public int ProductId", you would need a line defining the variable, in addition two methods (a getter and setter) as follows:
private int _productId;
public void setProductId(int anId)
{
_productId = anId;
}
public int getProductId()
{
return _productId;
}
You'd need to define similar variable declarations and getter/setter methods for each variable you have.
I've been trying for hours to get many-to-many relationship to save with Castle ActiveRecord. What am I doing wrong? I can't find anything in the documentation or on google. There is data in the database.
Courses have a many to many relationship with Books.
Test code.
Database.Course c = new Database.Course();
c.Number = "CS 433";
c.Name = "Databases";
c.Size = 34;
c.Books = Database.Book.FindAll();
c.Save();
Also doesn't work
foreach(Database.Book b in Database.Book.FindAll()){
c.Books.Add(b);
}
Database Classes
[ActiveRecord]
public class Course : ActiveRecordValidationBase<Course>
{
private int? id;
private string number;
private string name;
private string description;
private int size; //number of students in class
//references
private IList books = new ArrayList();
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
get
{
return string.Format("{0} - {1}", Number, Name);
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Number
{
get { return number; }
set { number = value; }
}
[Property, ValidateNonEmpty]
public string Name
{
get { return name; }
set { name = value; }
}
[Property(ColumnType="StringClob")]
public string Description
{
get { return description; }
set { description = value; }
}
[Property]
public int Size
{
get { return size; }
set { size = value; }
}
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id", Inverse = true)]
public IList Books
{
get { return books; }
set { books = value; }
}
}
[ActiveRecord]
public class Book : ActiveRecordValidationBase<Book>
{
private int? id;
private string title;
private string edition;
private string isbn;
private bool is_available_for_order;
//relations
private IList authors = new ArrayList();
private IList bookordercount = new ArrayList();
private IList courses = new ArrayList();
private Inventory inventory;
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
//*
get {
string str;
if (Edition == null || Edition == "")
str = Title;
else
str = string.Format("{0} ({1})", Title, Edition);
if (Authors.Count != 0)
{
return string.Format("{0} by {1}", str, FormattedAuthors);
}
else
{
return str;
}
}
/*/
get
{
return Title;
}
//*/
}
public string FormattedAuthors
{
get
{
if (Authors.Count == 0) return "";
StringBuilder sb = new StringBuilder();
int i = 0, end = Authors.Count;
foreach (Author a in Authors)
{
i++;
sb.Append(a.FormattedName);
if (i != end) sb.Append("; ");
}
return sb.ToString();
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Title
{
get { return title; }
set { title = value; }
}
[Property]
public string Edition
{
get { return edition; }
set { edition = value; }
}
[Property, ValidateNonEmpty]
public string Isbn
{
get { return isbn; }
set { isbn = value; }
}
[Property]
public bool IsAvailableForOrder
{
get { return is_available_for_order; }
set { is_available_for_order = value; }
}
//relations
[HasAndBelongsToMany(typeof(Author),
Table = "BookAuthor", ColumnKey = "book_id", ColumnRef = "author_id")]
public IList Authors
{
get { return authors; }
set { authors = value; }
}
[HasMany(typeof(BookOrderCount), Table = "BookOrderCounts", ColumnKey = "BookId")]
public IList BookOrderCount
{
get { return bookordercount; }
set { bookordercount = value; }
}
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id")]
public IList Courses
{
get { return courses; }
set { courses = value; }
}
[OneToOne]
public Inventory Inventory
{
get { return inventory; }
set { inventory = value; }
}
}
Make sure you put the Inverse = true where you want it. From the Castle AR docs,
It is wise to choose one side of the
relation as the owner. The other side,
the non-writable, need to use
Inverse=true.
Put the Inverse = true on the other side of the relationship, like this:
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id")]
public IList<Book> Books
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id", Inverse = true)]
public IList<Course> Courses
You also have to add attributes to the top of both classes - at the moment they don't know what tables they're mapped to. Currently you have this:
public class Course : ActiveRecordBase<Course>
Add this (where "course" is the name of your Course table):
[ActiveRecord("course")]
public class Course : ActiveRecordBase<Course>