How to make a chain calculation using OOP? [closed] - php

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 days ago.
The community is reviewing whether to reopen this question as of 4 days ago.
Improve this question
Given MyCalculator class
class MyCalculator
{
public float $a, $b, $c,
public MyCalculator $result;
public function __construct ($a, $b)
{
$this->a = $a;
$this->b = $b;
$this->result = new MyCalculator($this->c, 0)
}
public function add()
{
$this->result->c = $this->a + $this->b;
return $this->result->c;
}
public function divideBy($num)
{
$this->result->c = $this->result->c / $num;
return $this->result->c;
}
}
$calc = new MyCalculator(12, 6);
In my code works good either:
echo $calc->Add() // Displays: 15
or
echo $calc->Add()->DivideBy(3) // Displays: 5 ((6+9)/3=5)
But I cannot make them working both!

Based on the description of your problem, you will want to setup this class definition:
class MyCalculator
{
private $value1;
private $value2;
public $total;
public function __construct($value1, $value2, $total = null)
{
$this->value1 = $value1;
$this->value2 = $value2;
$this->total = $total;
}
public function add()
{
$this->total = $this->value1 + $this->value2;
return new MyCalculator(0, 0, $this->total);
}
public function divideBy($value)
{
return $this->total / $value;
}
}
What this does is set two required property values and one optional property value in the constructor, create an add method that returns a new instance of the class where the total matches the sum of the two values passed in the constructor, and creates a divideBy method that divides the current total by the desired number.
Here is an example of using it:
$calc = new MyCalculator(6, 9);
echo $calc->add()->divideBy(3);
Fiddle: https://onlinephp.io/c/498ed

Related

Return Object Instead of Array [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 months ago.
Improve this question
I really searched too much but i couldn't find anything. I'm newbie to classes that's why I'm getting trouble :)
My class is like below:
class Instagram
{
public array $account = [];
public function get_instagram_business_accounts(): array
{
return db()->query("SELECT followers_count FROM instagram_business_accounts ORDER BY username")->fetchAll();
}
public function get_followers_count()
{
return Miscellaneous::number_format($this->account["followers_count"]);
}
}
I'm using the above class like this:
$accounts = new Instagram();
foreach($accounts->get_instagram_business_accounts() AS $account){
$accounts->account = $account;
echo $accounts->get_followers_count();
}
But I want to use like this:
$accounts = new Instagram();
foreach($accounts->get_instagram_business_accounts() AS $account){
echo $account->get_followers_count();
}
I want to use $account as an object. How can I do this?
Best Regards,
=======
EDIT
I updated my main class like below:
class Instagram
{
public function get_instagram_business_accounts(): array
{
$accounts = db()->query("SELECT followers_count FROM instagram_business_accounts ORDER BY username")->fetchAll();
$return = [];
foreach($accounts AS $account){
$return[] = new InstagramAccount($account);
}
return $return;
}
}
And my InstagramAccount class is below:
class InstagramAccount
{
private int $followers_count;
public function __construct(array $Instagram)
{
foreach($Instagram AS $key=>$value){
$this->{$key} = $value;
}
}
public function get_followers_count(): string
{
return Miscellaneous::number_format($this->followers_count);
}
}
Now I do what i want, right?
get_followers_count() is a method of class Instagram. In your second code you try to call this method from $account which is an array. That doesn't work

how to handle the states of an object [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
What would be the correct way to handle the types of state that an object can have in an application?
For example, if i have an AcceptanceCriteria class, i need to verify if it is accepted, rejected or pending.
I usually do it by returning numbers that represent the state, but it does not seem like a good form, it can be confusing.
for example:
class AcceptanceCriteria
{
const PENDING = 0;
const ACCEPTED = 1;
const REJECTED = 2;
protected $state = self::PENDING;
public function accept():void
{
$this->state = self::ACCEPTED;
}
public function reject():void
{
$this->state = self::REJECTED;
}
public function state():int
{
return $this->state;
}
}
I need to check the state frequently and also show it in the front, what is a better way to do it? I dont want to check in the front if and acceptance criteria state is 0, 1 or 2 for do something.
How about some accessors that return booleans rather than ints so your algorithm is completely encapsulated?
class AcceptanceCriteria
{
const PENDING = 0;
const ACCEPTED = 1;
const REJECTED = 2;
protected $state = self::PENDING;
public function accept():void
{
$this->state = self::ACCEPTED;
}
public function reject():void
{
$this->state = self::REJECTED;
}
// Accessors
public function is_rejected():bool
{
return self::PENDING == $this->state;
}
public function is_accepted():bool
{
return self::ACCEPTED == $this->state;
}
public function is_rejected():bool
{
return self::REJECTED == $this->state;
}
}
Its good way to use strongly typed enums. You can use splEnum or smart implementation from My C-Labs.
First move your states to separated enum class
<?php
use MyCLabs\Enum\Enum;
class AcceptanceCriteriaStateEnum extends Enum
{
private const PENDING = 0;
private const ACCEPTED = 1;
private const REJECTED = 2;
}
then you can modify your class like bellow
class AcceptanceCriteria
{
protected $state = AcceptanceCriteriaStateEnum::PENDING;
public function setState(AcceptanceCriteriaStateEnum $state):void
{
$this->state = $state;
}
public function getState():int
{
return $this->state;
}
public function isInState(AcceptanceCriteriaStateEnum $checkState):bool
{
return $this->state == $checkState;
}
}
for checking state you can use method isInState which return boolean
$obj = new AcceptanceCriteria();
$obj->setState(AcceptanceCriteriaStateEnum::ACCEPTED);
// check status
echo $obj->isInState(AcceptanceCriteriaStateEnum::ACCEPTED);

echo OOP php method [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I had one lesson in OOP which included messaging between classes. On the tutorial, the guy just showed var_dump output version of that. I wanted to play with the code and change from var_dump to echo output, because it would me more useful in future. I just couldn't find any solution so you guys are my only option. Here's the code.
<?php
class Person {
protected $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
class Business {
// adding Staff class to Business
public function __construct(Staff $staff)
{
$this->staff = $staff;
}
// manual hire(adding Person to Staff)
public function hire(Person $person)
{
// add to staff
$this->staff->add($person);
}
// fetch members
public function getStaffMembers()
{
return $this->staff->members();
}
}
class Staff {
// adding people from Person class to "member" variable
protected $members = [];
public function __construct($members = [])
{
$this->members = $members;
}
// adding person to members
public function add(Person $person)
{
$this->members[] = $person;
}
public function members()
{
return $this->members;
}
}
// you can also create an array with this method
$bros = [
'Bro',
'Zdenko',
'Miljan',
'Kesten'
];
// pretty simple to understand this part
$employees = new Person([$bros]);
$staff = new Staff([$employees]);
$business = new Business($staff);
var_dump($business->getStaffMembers());
// or the print_r, it doesn't matter
print_r($business->getStaffMembers());
?>
Try to loop through the array and echo out every single value.
$array = $something //your assignment here
foreach($array as $key => $value ){
echo "$key => $value\n";
}

OOP - How to define what object create? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I ask your advise.
In my php file there are some classes.
class Template {
public $id;
public $title;
public $text;
public $description;
public $data = array();
public $content_html;
public $width_content = 500;
public $type;
public $time;
public $user;
public $category;
protected $CI;
// The next code works for a one element of array $data
function __construct($data = array()){
$this->title = $data['title'];
$this->text = $data['text'];
$this->category = $data['category'];
$this->type = $data['type'];
$this->time = $data['time'];
$this->CI =& get_instance();
$this->user = new InformationUser($data);
}
class Articles extends Template {
}
class News extends Template {
}
class Init {
public $posts = array('type' => 2);
}
The start point of my classes is a class Init.
Inside this class there is array of users posts.
In each element array there is a type value, which define what object class I must create.
For example:
class Init {
function define(){
foreach($this->posts as $val){
if($val['type'] == 2){
$article = new Articles($val);
//TODO $articles
} else if($val['type'] == 3){
$news = new News($val);
//TODO $news
}
}
}
}
I know that is variant is wrong, better to put all array posts() to class. But I can not do this.
I need, that for different type of element of array - to work separate class (for news - News class, article - class Article etc.)
What do you advise me?
From the minimal info provided.. I assume you are looking for something like this:
<?php
class Init {
public static function define($type, $text)
{
switch($type) {
case 1:
return new Articles($text);
break;
case 2:
return new News($text);
break;
default:
throw new Exception('Undefined type');
}
}
}
// $template = Init::define(1, 'article text');
// $template = Init::define(2, 'news text');

A simpler way to write the calculator class in OOP PHP

I have created a class called Calculator with the add, subtract, multiply and divide function. The calculator is limited to adding two numbers and returning the result.
I am relatively new to OOP,would like to get some input on the class, did i take the long route and if i did is there another way to simplify the class.
Here is the code:
class Calculator {
private $_val1 , $_val2;
public function __construct($val1, $val2){
$this->_val1 = $val1;
$this->_val2 = $val2;
}
public function add(){
return $this->_val1 + $this->_val2;
}
public function subtract(){
return $this->_val1 - $this->_val2;
}
public function multiply (){
return $this->_val1 * $this->_val2;
}
public function divide () {
return $this->_val1 / $this->_val2;
}
}
$calc = new Calculator(3,4);
echo "<p>3 + 4 = ".$calc->add(). "</p>";
$calc = new Calculator (15,12);
echo "<p>15 - 12 = ".$calc->subtract(). "</p>";
$calc = new Calculator (20,2);
echo "<p> 20 * 2 = ".$calc->multiply(). "</p>";
$calc = new Calculator (20,2);
echo "<p> 20 / 2 = ".$calc ->divide(). "</p>";
IMHO, you should use Polymorphism.
This Video may help you understanding this principle
Here's my way of thinking.
First, define an interface for any operations you'd need
interface OperationInterface
{
public function evaluate(array $operands = array());
}
Then, create the calculator holder
class Calculator
{
protected $operands = array();
public function setOperands(array $operands = array())
{
$this->operands = $operands;
}
public function addOperand($operand)
{
$this->operands[] = $operand;
}
/**
* You need any operation that implement the given interface
*/
public function setOperation(OperationInterface $operation)
{
$this->operation = $operation;
}
public function process()
{
return $this->operation->evaluate($this->operands);
}
}
Then you can define an operation, for example, addition
class Addition implements OperationInterface
{
public function evaluate(array $operands = array())
{
return array_sum($operands);
}
}
And you would use it like :
$calculator = new Calculator;
$calculator->setOperands(array(4,2));
$calculator->setOperation(new Addition);
echo $calculator->process(); // 6
With that point, if you want to add any new behaviour, or modify an existing one, just create or edit a class.
For example, say you want a Modulus operation
class Modulus implements OperationInterface
{
public function evaluate(array $operands = array())
{
$equals = array_shift($operands);
foreach ($operands as $value) {
$equals = $equals % $value;
}
return $equals;
}
}
Then,
$calculator = new Calculator;
$calculator->setOperands(array(4,2));
$calculator->setOperation(new Addition); // 4 + 2
echo $calculator->process(); // 6
$calculator->setOperation(new Modulus); // 4 % 2
echo $calculator->process(); // 0
$calculator->setOperands(array(55, 10)); // 55 % 10
echo $calculator->process(); // 5
This solution allows your code to be a third-party library
If you plan to reuse this code or give it away as a library, the user wouldn't by any case modify your source code.
But what if he wants a Substraction or a BackwardSubstraction method which are not defined ?
He just has to create his very own Substraction class in his project, which implements OperationInterface in order to work with your library.
It's easier to read
When looking in the project architecture it's easier to see a folder like this
- app/
- lib/
- Calculator/
- Operation/
- Addition.php
- Modulus.php
- Substraction.php
- OperationInterface.php
- Calculator.php
And immediatly know which file contains the desired behaviour.
I don't think a plain calculator is a good example for OOP. An object needs both a set of methods and a set of variables that represent its state, and can be used to differentiate instances of the object. I would suggest trying to make "moody" calculators. A calculator with a happy mood will add 2 to each result, and an angry calculator will subtract 2 from each result.
I would do something like this
interface Evaluable {
public function evaluate();
}
class Value implements Evaluable {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function evaluate() {
return $this->value();
}
}
class Node implements Evaluable {
protected $left;
protected $right;
public function __construct(Evaluable $left, Evaluable $right) {
$this->left = $left;
$this->right = $right;
}
}
class SumNode extends Node {
public function evaluate() {
return $this->left->evaluate() + $this->right->evaluate();
}
}
$op = new SumNode(new Value(2), new Value(3));
$result = $op->evaluate();
This way you can easyly add new operations
class SubNode extends Node {
public function evaluate() {
return $this->left->evaluate() - $this->right->evaluate();
}
}
And chain operations like this
$sum1 = new SumNode(new Value(5), new Value(3));
$sum2 = new SumNode(new Value(1), new Value(2));
$op = new SubNode($sum1, $sum2);
$result = $op->evaluate();
In general, we don't fix value in those kind of class.
Your methods should take their 2 values by arguments instead of picking private members.
Like the following:
public function add($v1, $v2)
{
return $v1 + $v2;
}
Thus, Calculator becomes a tool, and we should not need to allocate this kind of object.
That's why Calculators methods should be static.
public static function add($v1, $v2)
{
return $v1 + $v2;
}
In this way, all you need to call is Calculator::add(1, 2).
You can find those kinds of class everywhere. Like Vector, Matrice in math or 3D. Or write to the output or anything like that.
Remember, it is a way to do that, neither the best nor the worst.
you should probably end up doing something like
$calc = new Calculator();
$calc->sum($x, $y, $z);
$calc->substract($x, $y);
....
Take a look at this example. You can give any number of arguments like this using func_num_args()
<?php
function foo()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs\n";
}
foo(1, 2, 3);
?>
// output: Number of arguments: 3
This task has a lot of solutions, here is one of them:
<?
class Calculator
{
/**
* #var float
*/
/**
* #var float
*/
private $_val1,
$_val2;
/**
* #var int
*/
private static $_result = 0;
/**
* #param $val1
* #param $val2
*/
public function __construct($val1 = '', $val2 = '')
{
if ((!empty($val1) && !empty($val2)) && (!is_numeric($val1) && !is_numeric($val2))) {
$this->_val1 = (float)$val1;
$this->_val2 = (float)$val2;
}
}
/**
* #param $val1
*/
public function setVal1($val1)
{
$this->_val1 = (float)$val1;
}
/**
* #param $val2
*/
public function setVal2($val2)
{
$this->_val2 = (float)$val2;
}
/**
* #param string $operator
*
* #return float|int|string
*/
public function getResult($operator = '')
{
if (is_numeric($this->_val1) && is_numeric($this->_val2)) {
switch ($operator) {
case '+':
self::$_result = $this->_val1 + $this->_val2;
break;
case '-':
self::$_result = $this->_val1 - $this->_val2;
break;
case '*':
self::$_result = $this->_val1 * $this->_val2;
break;
case '/':
self::$_result = $this->_val1 / $this->_val2;
break;
}
} else {
echo 'Alert alert alert)) some of operands not set or not number';
}
return self::$_result;
}
}
And here is nice solution https://gist.github.com/cangelis/1442951

Categories