lsndr

To trait, or not to trait?

Whenever you implement a reusable collection of behavior, you will have to decide whether you want to use a trait or an abstract class. There is no firm rule, but this section contains a few guidelines to consider.

If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all.

If it might be reused in multiple, unrelated classes, make it a trait. Only traits can be mixed into different parts of the class hierarchy.

If you want to inherit from it in Java code, use an abstract class. Since traits with code do not have a close Java analog, it tends to be awkward to inherit from a trait in a Java class. Inheriting from a Scala class, meanwhile, is exactly like inheriting from a Java class. As one exception, a Scala trait with only abstract members translates directly to a Java interface, so you should feel free to define such traits even if you expect Java code to inherit from it. See Chapter 29 for more information on working with Java and Scala together.

If you plan to distribute it in compiled form, and you expect outside groups to write classes inheriting from it, you might lean towards using an abstract class. The issue is that when a trait gains or loses a member, any classes that inherit from it must be recompiled, even if they have not changed. If outside clients will only call into the behavior, instead of inheriting from it, then using a trait is fine.

If efficiency is very important, lean towards using a class. Most Java runtimes make a virtual method invocation of a class member a faster operation than an interface method invocation. Traits get compiled to interfaces and therefore may pay a slight performance overhead. However, you should make this choice only if you know that the trait in question constitutes a performance bottleneck and have evidence that using a class instead actually solves the problem.

If you still do not know, after considering the above, then start by making it as a trait. You can always change it later, and in general using a trait keeps more options open.

16 апреля   OOP   Traits

Python: Devide the number into random digits

Assume that we have an aim: divide a given number into defined number of random digits.The random digits must be equally distributed among all parts. So let’s try to write the code.

from random import randint

def devide_number(number, parts_number, allow_zero = False):
	"""
	Expand a given number into given number of digits.

	@param int $number Number
	@param int $parts_number Number of parts
	@param bool $allow_zero Let the function use zero in a result array

	@return bool|array
        """
	if (parts_number > number):
		raise ValueError("Number of parts can't be higher than the number");

	parts = []
	number_rest = number

	for i in range(1, parts_number + 1):
		if (i == parts_number):
			parts.append(number_rest)
			break
		else: 
			new_number = randint(0, number_rest) if allow_zero else randint(1, (number_rest - (parts_number - i)) // 2)

		number_rest -= new_number
		parts.append(new_number)

	return parts

Description

int $number — the given number.
int $parts_number — a number of parts.
bool $allow_zero — allow to use zero in result list

The function returns a list of digits or raise exception in case parts_number more than number.

Tests

Dividing 20 into 5 digits

Array
(
    [0] => 1
    [1] => 6
    [2] => 3
    [3] => 2
    [4] => 8
)

Dividing 143 into 7 digits

Array
(
    [0] => 65
    [1] => 12
    [2] => 19
    [3] => 3
    [4] => 22
    [5] => 2
    [6] => 20
)
20 февраля   Function   Python