Containers Array¶
some refs https://www.sandordargo.com/blog/2023/04/12/vector-of-unique-pointers
In [1]:
import ROOT
In [2]:
import fortranmagic
%load_ext fortranmagic
import os
import sys
import numpy as np
if sys.platform.startswith("win"):
# Depends of system, python builds, and compilers compatibility.
# See below.
f_config = "--fcompiler=gnu95 --compiler=mingw32"
else:
# For Unix, compilers are usually more compatible.
f_config = ""
# Disable only deprecated NumPy API warning without disable any APIs.
f_config += " --extra '-DNPY_NO_DEPRECATED_API=0'"
%fortran_config {f_config}
New default arguments for %fortran: --extra '-DNPY_NO_DEPRECATED_API=0'
c++¶
use it in real compiler such as gcc, clang or msvc: https://visualstudio.microsoft.com/de/vs/community/
In [3]:
%%cpp -d
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
class Geometry {
public:
Geometry() {}
virtual ~Geometry() = default;
virtual double getArea() = 0;
virtual double getCircumference() = 0;
};
class Rectangle1 :public Geometry {
public:
Rectangle1(double width, double height) :width(width), height(height) {//when exist c calles the standard constructor of the parent class
}
//virtual ~Rectangle() {}//destructor if not used leave it out
virtual double getArea() override {
return width * height;
}
virtual double getCircumference() override {
return 2 * (width + height);
}
protected: //can be only accessed by this class and children
private: //can only be accessed by this class
double width;
double height;
};
class Square :public Rectangle1 {
public:
Square(double l) :Rectangle1(l, l) {
}
};
class Disc :public Geometry {
public:
Disc(double r) :r(r) {
}
virtual double getArea() {
return 3.1415926 * r * r;
}
virtual double getCircumference() {
return 2 * 3.1415926 * r;
}
protected:
double r;
};
In [4]:
%%cpp
//void main()
{
Rectangle1 r(2.1, 3.1);
Square s(3.1);
Disc d(2.1);
cout << r.getArea() << endl;
cout << r.getCircumference() << endl;
cout << endl;
cout << s.getArea() << endl;
cout << s.getCircumference() << endl;
cout << endl;
cout << d.getArea() << endl;
cout << d.getCircumference() << endl;
std::vector<std::shared_ptr<Geometry>> v;
v.push_back(std::make_shared<Disc>(2.1));
v.push_back(std::make_shared<Rectangle1>(2.1, 3.1));
v.push_back(std::make_shared<Square>(3.1));
for (auto i : v)
{
std::cout << i->getArea() << std::endl;
}
}
6.51 10.4 9.61 12.4 13.8544 13.1947 13.8544 6.51 9.61
javascript¶
In [5]:
%%js //the next line is only necessary in jupyter notebooks
element.setAttribute('style', 'white-space: pre;');console.log=function(text){element.textContent+=text+"\n"}
class Geometry{
constructor() {
if (this.constructor == Geometry) {
throw new Error("Abstract classes can't be instantiated.");
}
}
getArea(){
throw new Error("Method 'getArea()' must be implemented.");
}
getCircumference(){
throw new Error("Method 'getCircumference()' must be implemented.");
}
}
class Rectangle extends Geometry{
constructor(width, height){
super();
this.width=width
this.height=height
}
getArea(){
return this.width*this.height;
}
getCircumference(){
return 2*(this.width+this.height);
}
}
class Square extends Rectangle{
constructor(l){
super(l,l);
}
}
class Disc extends Geometry{
constructor(r){
super();
this.r=r;
}
getArea(){
return Math.PI*this.r*this.r;
}
getCircumference(){
return 2*Math.PI*this.r;
}
}
let m=[];
m.push(new Rectangle(2.1,3.1))
m.push(new Square(3.1))
m.push(new Disc(2.1))
for(let i in m){
console.log(m[i].getArea())
}
Python¶
In [6]:
from abc import ABC, abstractmethod
import math
class Geometry(ABC):
@abstractmethod
def getArea(self):
pass
def getCircumference(self):
pass
class Rectangle(Geometry):
def __init__(self,width, height):
self.width=width
self.height=height
super().__init__()
def getArea(self):
return self.width*self.height
def getCircumference(self):
return 2*(self.width+self.height)
class Square(Rectangle):
def __init__(self,l):
super().__init__(l,l);
class Disc(Geometry):
def __init__(self,r):
self.r=r
super().__init__();
def getArea(self):
return math.pi*self.r*self.r
def getCircumference(self):
return 2*math.pi*self.r;
m=[]
m.append(Rectangle(2.1,3.1))
m.append(Square(3.1))
m.append(Disc(2.1))
for el in m:
print(el.getArea())
6.510000000000001 9.610000000000001 13.854423602330987
In [7]:
%%fortran
module shapes_mod
use iso_fortran_env, only : real64
implicit none
private
public :: geometry, rectangle1, square, disc
public :: make_rectangle1, make_square, make_disc
public :: box, push_back
! Abstract base "class"
type, abstract :: geometry
contains
procedure(getArea_if), deferred :: getArea
procedure(getCirc_if), deferred :: getCircumference
end type geometry
abstract interface
pure function getArea_if(self) result(a)
import :: geometry, real64
class(geometry), intent(in) :: self
real(real64) :: a
end function getArea_if
pure function getCirc_if(self) result(c)
import :: geometry, real64
class(geometry), intent(in) :: self
real(real64) :: c
end function getCirc_if
end interface
! Rectangle: concrete subclass
type, extends(geometry) :: rectangle1
private
real(real64) :: w, h
contains
procedure :: getArea => rect_area
procedure :: getCircumference => rect_circ
end type rectangle1
! Square: subclass of Rectangle1
type, extends(rectangle1) :: square
! Inherits area and circumference; no overrides needed
end type square
! Disc: concrete subclass
type, extends(geometry) :: disc
private
real(real64) :: r
contains
procedure :: getArea => disc_area
procedure :: getCircumference => disc_circ
end type disc
! Simple container element to allow mixed dynamic types in one array
type :: box
class(geometry), allocatable :: obj
end type box
contains
! "Constructors" (factory functions)
pure function make_rectangle1(width, height) result(x)
real(real64), intent(in) :: width, height
type(rectangle1) :: x
x%w = width
x%h = height
end function make_rectangle1
pure function make_square(l) result(x)
real(real64), intent(in) :: l
type(square) :: x
! Access to parent components is allowed within this module
x%w = l
x%h = l
end function make_square
pure function make_disc(rr) result(x)
real(real64), intent(in) :: rr
type(disc) :: x
x%r = rr
end function make_disc
! Implementations of virtuals
pure function rect_area(self) result(a)
class(rectangle1), intent(in) :: self
real(real64) :: a
a = self%w * self%h
end function rect_area
pure function rect_circ(self) result(c)
class(rectangle1), intent(in) :: self
real(real64) :: c
c = 2.0_real64 * (self%w + self%h)
end function rect_circ
pure function disc_area(self) result(a)
class(disc), intent(in) :: self
real(real64) :: a
real(real64), parameter :: pi = acos(-1.0_real64)
a = pi * self%r * self%r
end function disc_area
pure function disc_circ(self) result(c)
class(disc), intent(in) :: self
real(real64) :: c
real(real64), parameter :: pi = acos(-1.0_real64)
c = 2.0_real64 * pi * self%r
end function disc_circ
! A minimal push_back for a vector-like array of boxes
subroutine push_back(vec, g)
type(box), allocatable, intent(inout) :: vec(:)
class(geometry), intent(in) :: g
type(box), allocatable :: tmp(:)
integer :: n
if (.not. allocated(vec)) then
allocate(vec(1))
allocate(vec(1)%obj, source=g)
else
n = size(vec)
allocate(tmp(n+1))
tmp(1:n) = vec
allocate(tmp(n+1)%obj, source=g)
call move_alloc(tmp, vec)
end if
end subroutine push_back
end module shapes_mod
! program and subroutine exchanged due to jupyternotebook
! program main
subroutine main()
use iso_fortran_env, only : real64
use shapes_mod
implicit none
type(rectangle1) :: r
type(square) :: s
type(disc) :: d
type(box), allocatable :: v(:)
integer :: i
r = make_rectangle1(2.1_real64, 3.1_real64)
s = make_square(3.1_real64)
d = make_disc(2.1_real64)
print *, r%getArea()
print *, r%getCircumference()
print *
print *, s%getArea()
print *, s%getCircumference()
print *
print *, d%getArea()
print *, d%getCircumference()
call push_back(v, make_disc(2.1_real64))
call push_back(v, make_rectangle1(2.1_real64, 3.1_real64))
call push_back(v, make_square(3.1_real64))
do i = 1, size(v)
print *, v(i)%obj%getArea()
end do
! end program
end subroutine main
In [8]:
main()
6.5100000000000007 10.400000000000000 9.6100000000000012 12.400000000000000 13.854423602330987 13.194689145077131 13.854423602330987 6.5100000000000007 9.6100000000000012