# How to create this python object to julia

**URL:** <https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962>\
**Category:** New to Julia\
**Tags:** struct\
**Created:** [November 28, 2022, 6:15pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962 "2022-11-28T18:15:28Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![tryjulia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tryjulia/32/42826_2.png) [@tryjulia](https://discourse.julialang.org/u/tryjulia)\
**Post date:** [November 28, 2022, 6:15pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/1 "2022-11-28T18:15:28Z")

</div>

Hi, I have a code that I want to build on Julia, but I don’t know how to start on.

> class Point:  
> def **init** (self, center=(0,0)):  
> self.x = center[0]  
> self.y = center[1]
> 
> ```
> def print_point(self):
> print("The point is at ({x}, {y})".format(x=self.x, y=self.y))
> 
> ```
> 
> class Circle:  
> def **init** (self, center, radius):  
> self.center = Point(center)  
> self.radius = radius
> 
> ```
> def print_circle(self):
> print("The circle's center is at ({x}, {y}) and a radius of {radius}"
> .format(x=self.center.x, y=self.center.y, radius=self.radius))
> 
> ```
> 
> class Rectangle:  
> def **init** (self, tl, length, height):  
> #top left corner  
> self.tl = Point(tl)  
> self.length = length  
> self.height = height  
> #top right corner  
> self.tr = Point(((tl[0]+length), tl[1]))  
> #bottom left corner  
> self.bl = Point((tl[0], (tl[1]-height)))  
> #bottom right corner  
> self.br = Point(((tl[0]+length), (tl[1]-height)))
> 
> ```
> def print_rect(self):
> print("The corners of the rectangle are ({tl_x}, {tl_y}), ({tr_x}, {tr_y}), ({bl_x}, {bl_y}), ({br_x}, {br_y})"
> .format(tl_x=self.tl.x, tl_y=self.tl.y, 
> tr_x=self.tr.x, tr_y=self.tr.y,
> bl_x=self.bl.x, bl_y=self.bl.y,
> br_x=self.br.x, br_y=self.br.y))
> 
> ```
> 
> def point\_in\_circle(c, p):  
> if ((p.x \<= c.center.x+c.radius and p.x \>= c.center.x-c.radius) and  
> (p.y \<= c.center.y+c.radius and p.y \>= c.center.y-c.radius)):  
> return True  
> else:  
> return False
> 
> def rect\_in\_circle(c, r):  
> if (point\_in\_circle(c, r.tl) and point\_in\_circle(c, r.tr) and  
> point\_in\_circle(c, r.bl) and point\_in\_circle(c, r.br)):  
> return True  
> else:  
> return False
> 
> def rect\_circle\_overlap(c, r):  
> if (point\_in\_circle(c, r.tl) or point\_in\_circle(c, r.tr) or  
> point\_in\_circle(c, r.bl) or point\_in\_circle(c, r.br)):  
> return True  
> else:  
> return False

could I get some help? Thank you

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 28, 2022, 6:25pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/2 "2022-11-28T18:25:45Z")

</div>

It’s a pretty straightforward translation: you make a Julia struct type for each class in Python with appropriate constructors; for each method in Python you have a corresponding method in Julia with the additional freedom that the methods don’t have to live in one class or the other. What have you tried?

---

<div class="post-metadata">

**Author:** ![tryjulia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tryjulia/32/42826_2.png) [@tryjulia](https://discourse.julialang.org/u/tryjulia)\
**Post date:** [November 28, 2022, 6:32pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/3 "2022-11-28T18:32:24Z")

</div>

the thing is I have no experience in Python and I am a really newcomer for Julia so I don’t know where to start

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [November 28, 2022, 6:52pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/4 "2022-11-28T18:52:49Z")

</div>

This is a good place to start:

[Tutorials (julialang.org)](https://julialang.org/learning/tutorials/)

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [November 28, 2022, 6:59pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/5 "2022-11-28T18:59:56Z")

</div>

```julia
#=julia uses structs, they need to declare the fields and (optionally) the types of those fields.
when not declared, it normally hurts performance, but as a first example, its alright.
there is an extensive example of constructors of Point here: https://docs.julialang.org/en/v1/manual/constructors/#Parametric-Constructors
=#
struct Point
  x
  y
end

#external constructor, check:https://docs.julialang.org/en/v1/manual/constructors/#man-outer-constructor-methods
function Point(center)
  x,y = center
  #x = center[1] #julia uses one-based indexing
  #y = center[2]
  return Point(x,y)
end
#instead of defining a custom print method
#we are going to overload how Point shows in a REPL:

function Base.show(io::IO,::MIME"text/plain",data::Point)
  x,y = data.x, data.y
  println(io,"The point is at ($x,$y)")
end

struct Circle
  center::Point #we mark here that point should be of the point type
  radius
 #internal constructor, check https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods
  Circle(center,radius) = new(Point(center),radius)
end
#inline function
"""
  inside(big_thing,small_thing

function to determine if a thing is inside other thing. this is an example of documentation. returns true or false
"""
function inside(circ::Circle,point::Point)
  x0 = circ.center.x
  y0 = circ.center.y
  r = circ.radius
  x1 = point.x
  x2 = point.y
 return (x1 - x0)^2 + (y1 - y0)^2 <= r^2
end

#multiple dispatch, check https://docs.julialang.org/en/v1/manual/methods/
inside(::Point,::Point) = false

function inside(c1::Circle,c2::Circle)
   println("to be implemented")
  return false
end

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 28, 2022, 8:36pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/6 "2022-11-28T20:36:03Z")

</div>

That’s a good start, I would simplify a few things and to make it more idiomatic and efficient, add some type parameters. First, the type definitions:

```julia
struct Point{R<:Real}
  x :: R
  y :: R
end

abstract type ConvexShape{R} end

struct Circle{R<:Real} <: ConvexShape{R}
  center :: Point{R}
  radius :: R
end

struct Rectangle{R<:Real} <: ConvexShape{R}
  left :: R
  right :: R
  bottom :: R
  top :: R
end

Rectangle(p::Point, q::Point) =
  Rectangle(minmax(p.x, q.x)..., minmax(p.y, q.y)...)

# a matrix of the corners of a rectangle
corners(r::Rectangle) = [Point(x, y) for x in (r.left, r.right), y in (r.bottom, r.top)]

```

Now some geometric computational methods:

```julia
dist(p::Point, q::Point) = sqrt((p.x - q.x)^2 + (p.y - q.y)^2)

inside(p::Point, q::Point) = p == q
inside(p::Point, c::Circle) = dist(p, c.center) ≤ c.radius
inside(p::Point, r::Rectangle) =
  r.left ≤ p.x ≤ r.right && r.bottom ≤ p.y ≤ r.top

inside(c::Circle, c′::Circle) =
  c.radius + dist(c.center, c′.center) ≤ c′.radius
inside(c::Circle, r::Rectangle) =
  r.left ≤ c.center.x - c.radius && c.center.x + c.radius ≤ r.right &&
  r.bottom ≤ c.center.y - c.radius && c.center.y + c.radius ≤ r.top

inside(r::Rectangle, c::ConvexShape) =
  all(inside(p, c) for p in corners(r))

const ⊆ = inside

```

A few points about why I wrote things this way:

- Type parameters allow structs to be much more efficient and always have matching types for fields
- These allow you to use whatever real number type you want for the dimensions, e.g. `Float64`, `Int` or something slightly exotic like `Rational{BigInt}`
- No need to define constructors most of the time—the defaults just work
- Also no need to provide show methods often, the default is pretty good
- Since you can put types on arguments, it’s often clearer to use short argument names for math formulas—you can tell that `p` is a `Point` and `c` is a `Circle`, etc. from the method signature
- It is conventional in Julia to express “subject verb object” relationships as `verb(subject, object)`; accordingly one should read `inside(c::Circle, r::Rectangle)` as “`c` is inside `r`”; at the end I create `⊆` as an alias for `inside` which allows write this using infix operator notation as `c ⊆ r` which matches mathematical notation.

About the representation and construction of Rectangles:

- There are many ways to represent and construct this type
- I like `Rectangle(::Point, ::Point)` for construction because you don’t have to remember which corner is special or which which order the arguments are in—if you give any two points it constructs the rectangle between them
- Internal representation doesn’t really matter, but a list of left, right, bottom and top coordinates seems simple and allows easy construction from two points.

The only bit of type system cleverness here:

- I create an abstract type `ConvexShape` and make `Circle` and `Rectangle` implementations of it
- Checking if a rectangle is contained in any convex shape can be done by checking if all its corners are inside the convex shape, so we can define a single method

Note that the way these types are defined they work great if you use the same `Real` type everywhere (e.g. all `Int` or all `Float64`), but they start breaking as soon as you try mixing integers and floats for example. If you want to allow mixing types, then you can define these additional mixed type constructors for convenience:

```julia
Point(x::Real, y::Real) =
  Point(promote(x, y)...)

Rectangle(left::Real, right::Real, bottom::Real, top::Real) =
  Rectangle(promote(left, right, bottom, top)...)

function Circle(center::Point{R}, radius::S) where {R<:Real, S<:Real}
  T = promote_type(R, S)
  Circle(Point{T}(center.x, center.y), convert(T, radius))
end

```

Here’a a fun example that ends up using a lot of the above functionality:

```julia
julia> o = Point(0, 0) # origin
Point{Int64}(0, 0)

julia> c₁ = Circle(o, 1)
Circle{Int64}(Point{Int64}(0, 0), 1)

julia> c₂ = Circle(o, 2)
Circle{Int64}(Point{Int64}(0, 0), 2)

julia> c₁ ⊆ c₂
true

julia> c₁ ⊆ c₁
true

julia> c₂ ⊆ c₁
false

julia> r = Rectangle(Point(-1, -1), Point(1, 1))
Rectangle{Int64}(-1, 1, -1, 1)

julia> c₁ ⊆ r ⊆ c₂
true

```

---

<div class="post-metadata">

**Author:** ![tryjulia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tryjulia/32/42826_2.png) [@tryjulia](https://discourse.julialang.org/u/tryjulia)\
**Post date:** [November 30, 2022, 2:48am UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/7 "2022-11-30T02:48:07Z")

</div>

thank you! now I have another problem with this program. It shows errors and the worst part, I don’t know how to test the code. Please help, I’m kinda feel hopeless

> struct Time()  
> time = Time()  
> time.hour = 3  
> time.minute = 0  
> time.second = 0  
> end
> 
> function time\_to\_int(time)  
> minutes = time.hour \* 60 + time.minute  
> seconds = minutes \* 60 + time.second  
> return seconds  
> end
> 
> function int\_to\_time(seconds)  
> new\_time = Time()  
> minutes, new\_time.second = divmod(seconds, 60)  
> time.hour, time.minute = divmod(minutes, 60)  
> return time  
> end
> 
> function mul\_time(time, multicand)  
> time\_int = time\_to\_int(time) \* multicand  
> new\_time = int\_to\_time(time\_int)  
> if new\_time.hour \> 12  
> new\_time.hour = new\_time.hour % 12  
> println(“New time is: %.2d:%.2d:%.2d” % (new\_time.hour, new\_time.minute, new\_time.second))  
> return new\_time  
> end  
> end
> 
> mul\_time(time, 2)
> 
> function race\_stats(time, distance)  
> println(“The finish time was %.2d:%.2d:%.2d” % (time.hour, time.minute, time.second))  
> println(“The distance was %d miles” % (distance))  
> end  
> average = mul\_time(time, (1.0 / distance))
> 
> ```
> println("The average is: %.2d:%.2d:%.2d per mile" % (average.hour, average.minute, average.second))
> 
> ```
> 
> race\_stats(time, 3)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 30, 2022, 3:26am UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/8 "2022-11-30T03:26:51Z")

</div>

You seem to be having issues with basics of Julia syntax. You may want to start with an intro tutorial and make sure you can get that to work and then go from there. Once you’ve got a grip on the basic syntax you can come back to this specific example.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 30, 2022, 9:28am UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/9 "2022-11-30T09:28:38Z")

</div>

> [@tryjulia](#):
>
> struct Time()  
> time = Time()  
> time.hour = 3  
> time.minute = 0  
> time.second = 0  
> end

You should probably start by reading the Manual section on composite types and how to create them: [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#Composite-Types)

In particular, your syntax is way off. The above definition should be something like

```julia
struct Time
    hour::Int
    minute::Int
    second::Int
end
Time() = Time(3, 0, 0) # default constructor

```

---

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [November 30, 2022, 1:38pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/10 "2022-11-30T13:38:15Z")

</div>

> [@StefanKarpinski](#):
>
> Note that the way these types are defined they work great if you use the same `Real` type everywhere (e.g. all `Int` or all `Float64`), but they start breaking as soon as you try mixing integers and floats for example. If you want to allow mixing types, then you can define these additional mixed type constructors for convenience:

sorry, I‘m confuse about this sentence. If a struct is as follows:

```julia
struct Point
  x :: Int
  y :: Int
end

```

it can not accept Float64, and in REPL we can not redefinite a struct, so, why we need the new constructor function as follows?

```julia
Point(x::Real, y::Real) =
  Point(promote(x, y)...)

```

What’more , a snippet code in a REPL

```julia
julia> struct Point
         x :: Float64
         y :: Float64
       end

julia> Point(1.1, 1.2)
Point(1.1, 1.2)

julia> Point(1, 1.2)
Point(1.0, 1.2)

```

why `Point(1, 1.2)` works well? I know in julia `promote(1,1.2)`  
can promote 1 to 1.0, however, why it promotes automatically?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [November 30, 2022, 3:00pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/11 "2022-11-30T15:00:17Z")

</div>

> [@xuanquansheng](#):
>
> why we need the new constructor function as follows?

You need it if the struct is parametric:

```julia
struct Point{R<:Real}
    x::R
    y::R
end

```

If the definition simply requires `Float64`, the default constructor will try to convert every input to `Float64`, but in the parametric case, it doesn’t know what to convert to, since `Int` and `Float64` are _both_ `<:Real`.

```julia
julia> Point(2.3, 3)
ERROR: MethodError: no method matching Point(::Float64, ::Int64)

```

So then you specify that you want to promote:

```julia
julia> Point(x, y) = Point(promote(x, y)...);

julia> Point(2.3, 3) # now it works
Point{Float64}(2.3, 3.0)

```

---

<div class="post-metadata">

**Author:** ![xuanquansheng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xuanquansheng/32/32400_2.png) [@xuanquansheng](https://discourse.julialang.org/u/xuanquansheng)\
**Post date:** [November 30, 2022, 3:13pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/12 "2022-11-30T15:13:58Z")

</div>

Get it and thx. So it seems thatjulia need to to more work on type for mutidispatch and do more work on converting than other language?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [November 30, 2022, 3:48pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/13 "2022-11-30T15:48:05Z")

</div>

What makes you say that?

---

<div class="post-metadata">

**Author:** ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)\
**Post date:** [December 4, 2022, 6:50pm UTC](https://discourse.julialang.org/t/how-to-create-this-python-object-to-julia/90962/14 "2022-12-04T18:50:27Z")

</div>

[OpenAI API](https://beta.openai.com/examples/default-translate-code) OpenAI provides interesting interface to translate programming language. You should give it a try (even if that’s far from being perfect)
