In my continuing quest to improve my understanding of OPP in PHP, I have developed another project. It is closer to my field and a real life project I hope to develop, than my previous post using geometric shapes.

This draft program is the simplest version. I want to increase the complexity of this example and that requires more a complex class structure. I don't know how to do that. Here is the draft program.

class Country {
   private $name = 'default name';
   private $land;                  // The endowment of land in the country.
   private $labor;                 // The endowment of labor in the country.
   private $wheat;
   private $widgets;
   private $allocLand;             // The proportion of land in a country that is allocated to the production of wheat.
   private $allocLabor;            // The proportion of labor in a country that is allocated to the production of wheat.
   private $techfactor;            // A factor-neutal technology coefficient for the production function.
   private $wheatpower;            // The power coefficient on land in the production of wheat.  The function has constant returns to scale.
   private $widgetpower;           // The power coefficient on land in the production of widgets. The function has constant returns to scale.
   private $oppcost;               // The opportunity cost, in terms of wheat, of producing one additional widget.

   public function __construct($name, $land, $labor, $wheat, $widgets, $allocLand, $allocLabor, $techfactor, $wheatpower, $widgetpower, $oppcost) {
      $this -> name = $name;
      $this -> land = $land;
      $this -> labor = $labor;
      $this -> wheat = $wheat;
      $this -> widgets = $widgets;
      $this -> allocLand = $allocLand;
      $this -> allocLabor = $allocLabor;
      $this -> techfactor = $techfactor;
      $this -> wheatpower = $wheatpower;
      $this -> widgetpower = $widgetpower;
      $this -> oppcost = $oppcost;
}

   public function setName($Name) {
      $this -> name = $Name;
   }

   public function getName() {
      return $this -> name;
   }

   public function setLand($Land) {
      $this -> land = $Land;
   }

   public function getLand() {
      return $this -> land;
   }

   public function setLabor($Labor) {
      $this -> labor = $Labor;
   }

   public function getLabor() {
      return $this -> labor;
   }

   public function setWheat($Wheat) {
      $this -> wheat = $Wheat;
   }

   public function getWheat() {
      return $this -> wheat;
   }

   public function setWidgets($Widgets) {
      $this -> widgets = $Widgets;
   }

   public function getWidgets() {
      return $this -> widgets;
   }

   public function setAllocLand($AllocLand) {
      $this -> allocLand = $AllocLand;
   }

   public function getAllocLand() {
      return $this -> allocLand;
   }

   public function setAllocLabor($AllocLabor) {
      $this -> allocLabor = $AllocLabor;
   }

   public function getAllocLabor() {
      return $this -> allocLabor;
   }

   public function setTechfactor($Techfactor) {
      $this -> techfactor = $Techfactor;
   }

   public function getTechfactor() {
      return $this -> techfactor;
   }

   public function setWheatpower($Wheatpower) {
      $this -> wheatpower = $Wheatpower;
   }

   public function getWheatpower() {
      return $this -> wheatpower;
   }

   public function setWidgetpower($Widgetpower) {
      $this -> widgetpower = $Widgetpower;
   }

   public function getWidgetpower() {
      return $this -> widgetpower;
   }

   public function setOppcost($oppcost) {
      $this -> oppcost = $oppcost;
   }

   public function getOppcost() {
      return $this -> oppcost;
   }

   public function output($zz) {
      $wheat = $zz -> getTechfactor() * pow(($zz -> getLand() * $zz -> getAllocLand()), $zz -> getWheatpower()) * pow(($zz -> getLabor() * $zz -> getAllocLabor()), (1 - $zz -> getWheatpower()));
      $widgets = $zz -> getTechfactor() * pow(($zz -> getLand() * (1 - $zz -> getAllocLand())), $zz -> getWidgetpower()) * pow(($zz -> getLabor() * (1 - $zz -> getAllocLabor())), (1 - $zz -> getWidgetpower()));
      $zz -> setWheat($wheat);
      $zz -> setWidgets($widgets);
   }

   public function slope($zz) {
      $dy = $zz -> getTechfactor() * pow(($zz -> getLand() * $zz -> getAllocLand() - 0.1), $zz -> getWheatpower()) * pow(($zz -> getLabor() * $zz -> getAllocLabor() - 0.1), (1 - $zz -> getWheatpower())) - $zz -> getWheat();
      $dx = $zz -> getTechfactor() * pow(($zz -> getLand() * (1 - $zz -> getAllocLand()) + 0.1), $zz -> getWidgetpower()) * pow(($zz -> getLabor() * (1 - $zz -> getAllocLabor()) + 0.1), (1 - $zz -> getWidgetpower())) - $zz -> getWidgets();
      $zz -> setOppcost($dy / $dx);
   }
}


class View {
   public function __construct() {}

   public function printOutput($z) {
      echo "The country of " . $z -> getName() . " produced " . $z -> getWheat() . " bushels of wheat, and " . $z -> getWidgets() . " widgets.<br />";
   }

   public function printOppcost($z) {
      echo "The opportunity cost of producing a widget in " . $z -> getName() . " is " . abs($z -> getOppcost()) . " bushels of wheat.<br />";
   }
}

$alphastan = new Country('Alphastan', 100, 200, 0, 0, 0.73, 0.4, 1.25, 0.73, 0.50, 0);
$alphastan -> output($alphastan);
$alphastan -> slope($alphastan);

$betastan = new Country('Betastan', 200, 500, 0, 0, 0.58, 0.30, 1.50, 0.55, 0.40, 0);
$betastan -> output($betastan);
$betastan -> slope($betastan);

$v = new View();
$v ->printOutput($alphastan);
$v ->printOutput($betastan);
$v ->printOppcost($alphastan);
$v ->printOppcost($betastan);

The areas where I plan to increase the program's complexity is in the labor endowment, the amount of wheat and widgets produced, and the slope. I would like to sum the labor endowments for all the countries instantiated and make the labor used in production different from a country's labor endowment. I am sure that I need to do more than just make the labor properties public. A method must be developed to determine how much labor immigrates into or emigrates out of a country. I am not sure if that method, and related properties, are best located in the Country class or if a Labor class needs to be created for them.

I need to sum the wheat and widgets created in each country to determine world production amounts of wheat and widgets. These amounts will determine the amount of international trade in the world of these products. Again, I am not sure if different classes for wheat and widgets is best for the properties and methods associated with the imports and exports of these products between countries. So far to me, imports/exports seem to be a country property best left in the Country class, but not world production.

The opportunity cost property, the slope, needs to be compared across countries. That seems straightforward enough by making it public. The result of the comparison is something called comparative advantage and that is a factor in how much wheat and widgets each country produces. Again, these seem appropriate in the Country class, but as they relate to world production, they may need to be accessible to another class.

Thanks in advance. If further clarification of the project is needed I will provide it.

From your samples I wonder if you want to build a "world" class containing all the countries. Basically it contains a list/array of countries, and will have access to the country properties needed to show or compare. Something like this:

class World
    private Countries

    public AddCountry(name, land, etc)
    public Compare(country1, country2)
    public GetEndowment(country)
    public GetEndowments()

Your methods will return a data object with the information you need. This is a data-only object you can then pass to the view.

In a prior version, the Country class was abstract and I extended it for individual countries. I found that I was repeating the same class for each country.

Pritaeas, I am trying to grasp what you are suggesting. I would NOT be instantiating countries in the World class, as I do with my current version, correct? Each country would be a property of whatever is instantiated in the World class. What exactly gets instantiated? What is the object? What do you mean by "Your methods will return a data object with the information you need."?

Your getEndowments() function gives me an idea. I should be able to determine total Labor endowments in the world using 'foreach' to loop through the countries. The same for world production of wheat and widgets. As it stands now, these variables (world labor, world wheat, world widgets) would be scalars that are not associated with any object, correct?

I would NOT be instantiating countries in the World class, as I do with my current version, correct?

No, you would actually. At least that is my opinion. Since the world consists of a collection of countries, that would be the object that initializes them, most likely using a method containing the relevant data (what now gets passed to the Country ctor) as parameters.

class World
{
    private countries;

    public AddCountry($name, $land, $labor, ...)
    {
        $this->countries[] = new Country($name, $land, $labor, ...);
    }
}

What do you mean by "Your methods will return a data object with the information you need."?

As it stands now, these variables (world labor, world wheat, world widgets) would be scalars

I wasn't sure whether you'd need a single scalar as a result, or maybe more variables at once as a result (like the array/object mysql_query returns), hence data object instead of scalar.

I think the instantiation of countries works better as follows:

class View {
   public function __construct() {}

   public function printOutput($z) {
      echo "The country of " . $z -> getName() . " produced " . $z -> getWheat() . " bushels of wheat, and " . $z -> getWidgets() . " widgets.<br />";
   }

   public function printOppcost($z) {
      echo "The opportunity cost of producing a widget in " . $z -> getName() . " is " . abs($z -> getOppcost()) . " bushels of wheat.<br />";
   }

   public function worldTotals($z) {
      $totalLabor = 0;
      $totalWheat = 0;
      $totalWidgets = 0;
      foreach ($z as $key => $g)  {
         $totalLabor += $g -> getLabor();
         $totalWheat += $g -> getWheat();
         $totalWidgets += $g -> getWidgets();
      }
      echo "The total quantity of labor in the world is " . $totalLabor . " worker-years.<br />";
      echo "The world production of wheat is " . $totalWheat. " bushels, and the world production of widgets is " . $totalWidgets . " units.<br />";
   }
}


$country[0] = new Country('Alphastan', 100, 200, 0, 0, 0.75, 0.4, 1.25, 0.73, 0.50, 0);
$country[0] -> output($country[0]);
$country[0] -> slope($country[0]);

$country[1] = new Country('Betastan', 200, 500, 0, 0, 0.60, 0.30, 1.50, 0.55, 0.40, 0);
$country[1] -> output($country[1]);
$country[1] -> slope($country[1]);

$v = new View();
$v -> printOutput($country[0]);
$v -> printOutput($country[1]);
$v -> printOppcost($country[0]);
$v -> printOppcost($country[1]);
$v -> worldTotals($country);

So far, having the countries as a vector, permits the computation of world values by looping over the rows of the vector of countries. I need to figure out how to work with the world totals. I may need to change the class structure to get what I want, imports and exports.

Nathaniel there are many things in your code that I have comments . Before organizing objects in collections first you should understand what you are doing (in my opinion).
You have an object that you call it Country there your argument have many inconsistencies. You pass some with capital the firts letter e.g. $AllocLand and other normal e.g. $oppcost . I have talked you prior about camelCase in arguments but if you like one other paradigm just stick to it.

Then the object itself (not the class) has some methods that deal with other objects without even type hinting e.g. output($zz) . The $zz is really a bad name and more over there anyone can pass everything without type hinting. Why the instance can accept other instances and do something with them ? If it is a nature of this object no instance should be passed as argument and the object should use $this itself . If it isn't we are talking about another class that is a Utility of this one.

We are far away of talking about collection and lists of objects in PHP

OK. I am stuck.

I have no code to show, but I will describe my predicament with pseudo-code.

I am able to arrive at the amount of wheat and widgets that each country produces in its own country. I use arbitrary prices of wheat and widgets in each country. I can set arbitrary international prices for wheat and widgets which will be the prices for imports and exports. I can set an international price of wheat that is higher than the price of wheat in Alphastan but lower than that in Betastan. Alphstan will import wheat at the lower international price and Betstan will export wheat at the higher price. The opposite for widgets so that Alphastan will export widgets and Betastan will import widgets.

I can make the international price a scalar. I think I need to access the Alphastan and Betastan objects simultaneously because the amount of wheat that Alphastan imports must equal the amount of wheat that Betastan exports. That is impossible the way I have currently structured the Country class.

variable international price of wheat;
variable international price of widgets;

value of total production = domestic price of wheat times amount wheat produced + 
   domestic price of widgets times amount of widgets produced;

value of total consumption = international price of wheat times (amount of wheat produced + 
   amount of wheat imported (or minus international price times amount of wheat exported)) +
   international price of widgets times (amount of widgets produced + amount of widgets imported 
   (or minus international price times amount of widgets exported));

// The value of production in a country before international trade must equal the value 
// of consumption in a country after international trade.

while (abs(value of production - value of consumption) > 0.01) {
   adjust production of wheat and widgets by changing the amount of labor allocated to each product;
   value of production = domestic prices times production;
   value of consumption = international prices times (production +/- imports/exports);
   mechanism to change allocation of labor;
}   

How can I structure the classes to allow the function I described in pseudo=code? Or is it even possible?

Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.