How to change Enum possible values - traits

The following code does not work:
from traits.api import HasTraits, Enum
class A(HasTraits):
enum = Enum(1,2,3)
class B(A):
def __init__(self):
self.trait('enum').default_value = ['one','two','three']
b = B()
b.configure_traits()
Instead of having the choice ['one','two','three'] in the drop-down list, it is still [1,2,3]. Is there a way to modify an Enum content in any way after it has been declared once?

If you want to change the value of the enum trait when you subclass B from A, you can just redefine the trait like so:
class B(A):
enum = Enum(['one', 'two', 'three'])
If you want to be able to change the values in the Enum dynamically, the Enum constructor takes a values argument that you can pass the name of another trait that holds a sequence like a List trait that defines the values, like below, and then change the values in that list or the sequence in its entirety in any way you desire:
from traits.api import Enum, HasTraits, List
class A(HasTraits):
values = List([1, 2, 3])
enum = Enum(values='values')
a = A()
a.configure_traits()

Related

Declaring computed python-level property in pydantic

I have a class deriving from pydantic.BaseModel and would like to create a "fake" attribute, i.e. a computed property. The propery keyword does not seem to work with Pydantic the usual way. Below is the MWE, where the class stores value and defines read/write property called half with the obvious meaning. Reading the property works fine with Pydantic, but the assignment fails.
I know Pydantic is modifying low-level details of attribute access; perhaps there is a way to define computed field in Pydantic in a different way?
import pydantic
class Object(object):
def __init__(self,*,value): self.value=value
half=property(lambda self: .5*self.value,lambda self,h: setattr(self,'value',h*2))
class Pydantic(pydantic.BaseModel):
class Config:
extra='allow'
value: float
half=property(lambda self: .5*self.value,lambda self,h: setattr(self,'value',h*2))
o,p=Object(value=1.),Pydantic(value=1.)
print(o.half,p.half)
o.half=p.half=2
print(o.value,p.value)
outputs (value=1. was not modified by assigning half in the Pydantic case):
0.5 0.5
4 1.0
I happened to be working on the same problem today. Officially it is not supported yet, as discussed here.
However, I did find the following example which works well:
class Person(BaseModel):
first_name: str
last_name: str
full_name: str = None
#validator("full_name", always=True)
def composite_name(cls, v, values, **kwargs):
return f"{values['first_name']} {values['last_name']}"
Do make sure your derived field comes after the fields you want to derive it from, else the values dict will not contain the needed values (e.g. full_name comes after first_name and last_name that need to be fetched from values).
Instead of using a property, here's an example which shows how to use pydantic.root_validator to compute the value of an optional field:
https://daniellenz.blog/2021/02/20/computed-fields-in-pydantic/
I've adapted this for a similar application:
class Section (BaseModel):
title: constr(strip_whitespace=True)
chunks: conlist(min_items=1, item_type=Chunk)
size: typing.Optional[ PositiveInt ] = None
role: typing.Optional[ typing.List[ str ]] = []
license: constr(strip_whitespace=True)
#root_validator
def compute_size (cls, values) -> typing.Dict:
if values["size"] is None:
values["size"] = sum([
chunk.get_size()
for chunk in values["chunks"]
])
return values
In this case each element of the discriminated union chunks has a get_size() method to compute its size. If the size field isn't specified explicitly in serialization (e.g., input from a JSON file) then it gets computed.
Created a pip package that allows you to easily create computed properties.
Here you can check it out:
https://pypi.org/project/pydantic-computed/
By using the package the example with getting the half of a value would look like this :
from pydantic import BaseModel
from pydantic_computed import Computed, computed
class SomeModel(BaseModel):
value: float
value_half: Computed[float]
#computed("value_half")
def compute_value_half(value: float):
return value / 2

In Kotlin, is it possible to set different enum values to different objects, similar to how Python handles enum values?

I want to create a color class in Kotlin, that takes in an RGB value. I also plan on adding hex values but that doesn't pertain to the question. I would have two classes, then.
data class RGB(val red: Int, val green: Int, val blue: Int)
The RGB Class just stores three ints.
class Color(rgb: RGB)
The Color class just stores an RGB value. (I'm doing it this way because I plan to add a secondary constructor to Color that excepts a hex object instead.)
I want to have an enumeration that stores several generic colors, but I want each value in the enum to actually be a color object, not just store one. My current Colors enum is as follows.
enum class Colors(color: Color) {
WHITE(Color(RGB(255,255,255))),
//Some other colors
BLACK(Color(RGB(0,0,0)));
}
The issue I have with this is that I can't pass these values into a color parameter or set a color object equal to them (because they aren't colors, and just store them).
In Python, for enumerations, you can actually set enum values as objects, and therefore can be used in place of any object of that type. I don't remember the syntax exactly, but it was something along the lines of
class Colors(enum) {
WHITE = Color(RGB(255,255,255)),
//Some other colors
BLACK = Color(RGB(0,0,0));
}
This way if I have some method with a parameter of type color
//We've moved back into Kotlin
fun someMethod(color: Color) {
//Color some stuff
}
I can actually pass in an object from the enum.
someMethod(Colors.WHITE)
I am aware that using my current Kotlin enum, I can just call Colors.WHITE.color but I just want to know if I can do it the Python way. My Colors enum is just an example, but I have other uses where it is more important.
TL;DR I want to be able to use polymorphism on individual enum values, by setting them equal to objects. I want to be able to pass them into parameters of type X by setting them equal to X(parameters)
I often see that people use an Enum as a way of defining some constants - they do not necessarily want to take advantage of some ordinal value, or the closed set of members.
If you want to take advantage of a closed set of members property of an Enum type thing, then a sealed class could be your solution. A sealed class has a fixed set of implementations, so you can have things like switch/when statements that know they have exhuasted all cases in the set.
As an aside, this property is what makes sealed class the perfect tool for implementing aglebraic data types in a way that keeps your handling of a value that could be one of several completely different things safe. Eunms are all the same thing and have the same functions, a sealed class could consist of objects and instances that have nothing in common.
Here is an example.
import java.awt.Color
sealed class MyColor(r: Int, g: Int, b: Int) : Color(r, g, b) {
object WHITE : MyColor(255, 255, 255)
object BLACK : MyColor(0, 0, 0)
}
fun doSomethingWithAColor(color: Color) {
//Your Stuff
}
fun main() {
val color: MyColor = MyColor.WHITE
// This when clause is able to know that it has handled every case or not
when (color) {
MyColor.WHITE -> doSomethingWithAColor(color)
MyColor.BLACK -> doSomethingWithAColor(color)
}
}
If all you actually want is a set of constants, the sealed class solution provides that, but a normal old static class with immutable members and a private constructor will do. Here is an example, and it will work the same way as the example above.
class MyColor private constructor(r: Int, g: Int, b: Int): Color(r,g,b){
companion object{
val WHITE = MyColor(255, 255, 255)
val BLACK = MyColor(0, 0, 0)
}
}
If you do want to take advantage of an Enum's ordinal value (but from your python example I don't think you do) then I am afraid I am out of solutions that come out of the box. I think you would need to just provide more custom functions on your top level class to mimic that sort of number to instance mapping and have the type inheritance you are looking for.

How does EnumClass.values() work in Kotlin?

How does EnumClass.values() work in Kotlin?
I mean will it create new Array every time, or it is lazy evaluated static, or something else?
While not 100% sure, I assume that in Kotlin (as well as in Java) Enum.values() method is generated by the compiler:
The compiler automatically adds some special methods when it creates
an enum. For example, they have a static values method that returns an
array containing all of the values of the enum in the order they are
declared. This method is commonly used in combination with the
for-each construct to iterate over the values of an enum type.
From the JLS:
/**
* Returns an array containing the constants of this enum
* type, in the order they're declared. This method may be
* used to iterate over the constants as follows:
*
* for(E c : E.values())
* System.out.println(c);
*
* #return an array containing the constants of this enum
* type, in the order they're declared
*/
public static E[] values();
This method returns new array every time.
The point is that an array can't be constant in Java: it values can be modified, so you can't share the same array and have to give a new one on every access to guarantee that the array hasn't been changed.
Simple test:
enum class MyEnum { CAT, DOG }
val a = MyEnum.values()
val b = MyEnum.values()
println("${a === b}") // >>> false
a[0] = MyEnum.DOG
println(a.joinToString()) // >>> [DOG, DOG]
println(MyEnum.values().joinToString()) // >>> [CAT, DOG]

Iterate enum values using values() and valueOf in kotlin

Am a newbie here. Can anyone give an example to iterate an enum with values and valueOf methods??
This is my enum class
enum class Gender {
Female,
Male
}
I know we can get the value like this
Gender.Female
But I want to iterate and display all the values of Gender. How can we achieve this? Anyhelp could be appreciated
You can use values like so:
val genders = Gender.values()
Since Kotlin 1.1 there are also helper methods available:
val genders = enumValues<Gender>()
With the above you can easily iterate over all values:
enumValues<Gender>().forEach { println(it.name) }
To map enum name to enum value use valueOf/enumValueOf like so:
val male = Gender.valueOf("Male")
val female = enumValueOf<Gender>("Female")
You're getting [LGender;#2f0e140b or similar as the output of printing Gender.values() because you're printing the array reference itself, and arrays don't have a nice default toString implementation like lists do.
The easiest way to print all values is to iterate over that array, like this:
Gender.values().forEach { println(it) }
Or if you like method references:
Gender.values().forEach(::println)
You could also use joinToString from the standard library to display all values in a single, formatted string (it even has options for prefix, postfix, separator, etc):
println(Gender.values().joinToString()) // Female, Male
You can add this method to your enum class.
fun getList(): List<String> {
return values().map {
it.toString()
}
}
And call
val genders = Gender.getList()
// genders is now a List of string
// Female, Male
You can do this and get a new array of your enum type Gender
val arr = enumValues<Gender>()
and if you want a list of its, you can use the extension. toList()

Restrict Constructor Access

I have a type like this
sealed class Foo[A](val value: A)
object Foo {
def apply[A](v: A)(implicit num: Numeric[A]): Foo[A] =
/* highly complex stuff to make a Foo[A] */
implicit def toA[A](x: Foo[A]) = x.value
}
Foo as a class is only supposed to hold the value, so an implicit Numeric would not make much sense. But I need the type of A to be always a numeric.
So my idea is to just make it impossible to use Foos normal constructor outside of its companion. Is that possible in Scala?
Yeah, since the companion object can access private members of its companion class you can just make the primary (and auxiliary if any) constructor private.
Pseudo code here:
class ConcreteFoo private (n: Int) extends Foo(n)