You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""Kotlin Quick Guide
visitors license

This is a quick start guide to Kotlin for people with prior coding experience (in any other language). I compiled what I learned from different sources like Kotlin Koans and JetBrains Academy, as a quick reference while working on coding challenges or Android applications. This guide is in no way a complete reference to Kotlin, but it probably will be sufficient for new users. I’ve assumed you already know programming in some other language, so I have skipped explanations for concepts like mutability and lambda expressions. However, if you are new to such terms, a simple web search will definitely help you undertand them.

A sample Hello-World program has been included in the src directory to give you an idea of how Kotlin files and packages look like.

Table of Contents
Basic Facts
Values and Variables
Data Types
Type Conversion
Type Inference
Null Safety
Standard Input/Output
Functions and Lambda Expressions
Standard Library
Control Flow Statements
Object Oriented Programming
Working With Files
Learn Kotlin

Basic Facts

  • Blocks of code are enclosed in curly braces, {...}

  • Each statement should start on a new line

  • There are three types of comments in Kotlin:

// This is a single line comment

/* This is an example of
   a multiline comment. */

  * These are
  * documentation comments.
  • &&, ||, ! and xor represent the logical operators – and, or, not and xor.

Values and Variables

  • val is used to declare read-only values.

val name = "Kotlin"
name = "Programming"   // won't work, as 'name' is read-only and cannot be reassigned
  • var is used to declare mutable variables. You can reassign the variables with values of the same type as the initial value.

var language = "English"
language = "Klingon"   // this is possible
language = 10   // won't work, as language is a String variable
  • The variables type is inferred by the compiler. This is called type inference.

  • The type of a variable can be specified, if required, while declaring it. The type should be specified if the variable is not initialized during declaration, as the compiler cannot automatically infer the type.

var name: String = "Kotlin"
val num: Int = 999
val foo   // won't work, as type can't be inferred
val character: Char
character = 'A'   // works as expected
  • If you create a variable and assign an object to it, the new variable can point to the same object as well. This is called copying by reference. In other words, the = sign does not copy the object itself, it only copies a reference to it.

val msg1 = "Hey"
val msg2 = msg1
// msg1 and msg2 will both point to a single object in memory, the String "Hey".
  • If the object is immutable, you cannot change it, but you can use another object and assign this new object to the same variable. When you reassign the variable, it will point to the new object and other variables will still point to the old object. Standard types such as strings or numbers are immutable, so it’s safe to copy them by reference. The behavior of mutable objects is different. If you modify an object from one variable, the other assigned variables continue to point to that object, so they will also reflect the same changes.

  • If mutable types like lists or arrays are declared with the val keyword, the reference to the object is declared as read-only. However, the contents of the mutable type are still modifiable. In other words, if you declare a variable of type Array using val, you cannot reassign another Array to it, but you can change the values in the original Array.

  • The comparison operators == and != checks for structual equality, while === and !== checks for referential equality.

val blue = Box(3)
val green = blue   // object reference is copied
val red = Box(3)

println(blue == green)  // true
println(blue === green) // true, as both point (refer) to the same object
println(blue == red)   // true
println(blue === red)  // false, they point (refer) to different objects

var two = 2
var anotherTwo = 2

println(two === anotherTwo) // true, because the '===' equality check is equivalent to the '==' check for primitive types
two = two + 1
println(two === anotherTwo) // false
  • The val keyword implies an immutable reference to the object. The var keyword implies a mutable reference to a variable, so you can reassign it.

  • Kotlin supports prefix and postfix increment/decrement operators (++ and --) on variables.

Data Types

  • The names of Kotlin datatypes start with a capital letter.

  • Types:
    Byte: 8 bits (1 byte), Range: -128 to 127
    Short: 16 bits (2 bytes), Range: -32768 to 32767
    Int: 32 bits (4 bytes), Range: −(231) to (231)−1
    Long: 64 bits (8 bytes), Range: −(263) to (263)−1
    Float: 32 bits (4 bytes), 6-7 significant decimal digits
    Double: 64 bits (8 bytes), 15-16 significant decimal digits
    Char: 16 bits (2 bytes), represents a 16-bit Unicode character
    Boolean: size is machine-dependent
    String: size depends on the string

  • Strings are enclosed in double quotes, "...".

  • Characters are enclosed in single quotes, '_'.

  • Fractional numbers are inferred as Double by default. Explicitly specify the type, or use the suffix f or F to use Float instead.

  • Long is used by the compiler only if the value won’t fit in an Int variable. To use Long with a small value, explicitly specify the type of the variable, or use the suffix l or L with the value.

  • Underscores can be used to divide the a number into blocks for easier readability. 1_000_000 is the same as 1000000.

  • Types in Kotlin are organized into a hierarchy of subtype-supertype relationships. Supertype is a type that specifies some common characteristics and rules of behavior that every subtype will follow.

  • Number is a supertype for all types that represent numeric value. For example, Int, Float and Double are subtypes of Number type.

  • The type checker of the Kotlin compiler also enforces supertype-subtype relationships. For example, to a function waiting for an argument of type Number, you can pass its subtype, Int:

fun calc(number: Number) { /*...*/ }

val number: Int = 1
  • Any is a supertype for all non-nullable types in Kotlin. Any? is a supertype for Any that includes every other nullable type.

  • Unit is the equivalent of the void type found in many other programming languages. It is the return type of a function that does not return any meaningful value. If the return type of a function is not specified, it is inferred to be Unit. A return statement is not required for such functions as they are returned implicitly. Unit is also a subtype of Any.

  • Nothing is a type that has no instances, and are used in functions like fail() or expressions like throw, which doesn’t return control. Any code following an expression of type Nothing is unreachable. When you call a function with a Nothing return type, the compiler won’t execute any code beyond this call.

  • If you use null to initialize a value of an inferred type and there’s no other information that can be used to determine a more specific type, the compiler will infer the Nothing? type:

val x = null           // type: Nothing?
val l = listOf(null, null)   // type: List<Nothing?>
  • In Kotlin, 0 is not the same as false. So you cannot assign a Int value to a Boolean variable.

  • Small errors may accumulate after operations involving Float and Double types. Generally, avoid using == in expressions involving floating-point operations.

val one = 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1
println(one) // 0.9999999999999999
// one == 1.0 will return false
  • A Char can be also created by using its hexadecimal code in the Unicode table. They are interconvertible with Int values.

val alphabet = '\u0041'     // represents 'A'
  • Int numbers can be added to characters, but the reverse is not true.

var ch = 'a'

val ch1 = ch + 1      // 'b'
val ch2 = 1 + ch      // Error

ch += 2               // 'c'
  • You can compare Char using relational operators according to their position in the Unicode table.

  • The Char class has built-in utility functions like isDigit(), isLetter(), isLetterOrDigit(), isWhitespace(), isUpperCase(), isLowerCase(), toUpperCase() and toLowerCase().

  • String has a property length that stores the number of characters in the string. Individual elements can be accessed using their indices. It also has functions like first(), last() and lastIndex() to improve readability.

val text = "Hello!"

println(text.length)      // 6
println(text.first())     // H
println(text.last())      // !
println(text.lastIndex()) // 5
  • Individual characters of a String can’t be changed, because it is an immutable type.

  • String objects can be concatenated using the + operator. Values of other types can also be appended to a String using the + operator, but the expression must start with the String.

val firstName = "John"
val lastName = "Doe"
val fullName = lastName + ", " + firstName      // Doe, John
val userName = "johnny" + true + 69             // johnnytrue69
val nickname = 8 + "ball"                   // Error, as a string can't be added to an Int
  • Kotlin supports string templates. Variables can be used directly in a String by prefixing the dollar sign ($) to the variable name. Similarly, expressions can be used in a String by enclosing them in curly braces after the dollar sign.

val name = "John"

println("My name is $name.")                      // My name is John.
println("My name has ${name.length} letters.")    // My name has 4 letters.
  • The substring() method of a String accepts startIndex and lastIndex as arguments and returns the substring that starts at the startIndex and ends right before the lastIndex. If lastIndex is omitted, the default value (length of the original string) is used.

  • The substringBefore() and substringAfter() functions of String accept a delimiter as argument and return a String before/after the first occurrence of the specified delimiter. If the String does not contain the delimiter, the entire String is returned. Similarly, the substringBeforeLast() and substringAfterLast() methods return a String before or after the last occurrence of the delimiter. If a second argument is provided to these methods, it is returned if the delimiter is not found in the String.

  • The replace() method of a String replaces all occurrences of the first argument in the String with the second argument. Similarly, replaceFirst() replaces the first occurrence of the first argument with the second, and skips the rest.

  • The toLowerCase() and toUpperCase() methods of a String returns a String with its case converted accordingly.

  • The repeat() method of String allows you to repeat a String without using loops.

print("Hey".repeat(5))      // HeyHeyHeyHeyHey
  • A CharArray can be converted to a String using String(), and a String can be converted to a CharArray using the toCharArray() method. The toTypedArray() method can be used to convert an list of String to a TypedArray.

val chars = charArrayOf('A', 'B', ' ', 'C', 'D')
val text = String(chars)                                        // "AB CD"
val charsFromString = text.toCharArray()                        // { 'A', 'B', ' ', 'C', 'D' }
val words1: List<String> =  text.split(" ")                     // { "AB", "CD" }
val words2: Array<String> = text.split(" ").toTypedArray()      // { "AB", "CD" }
  • You can iterate through a String using a range of indices, array of indices, or using the characters of the String.

val text = "Hello World"

for (i in 0 until text.length) {
    print("${text[i]} ")              // H e l l o  W o r l d

for (index in text.indices) {
    print("${text[index]} ")          // H e l l o  W o r l d

for (i in text) {
    print("$i ")                      // H e l l o  W o r l d

Type Conversion

  • Unlike some other programming languages, there are no implicit widening conversions for numbers in Kotlin. For example, an Int variable cannot be initialized with a Short or Byte variable. A function with a Double parameter can be called only on Double values, but not Float, Int, or other numeric values. The compiler will not perform any automatic type conversion in these cases.

  • There are methods built into the datatypes for explicit type conversion. It will not affect the type of the original variables.

  • Every number type supports the following conversions:
    toByte(), toShort(), toInt(), toLong(), toFloat(), toDouble() and toChar().

  • Numbers are converted to Char and vice versa using the Unicode Table.

  • When you convert a larger type to smaller type, the value may be truncated.

  • All datatypes can be converted to a string using toString().

  • Strings can be converted to numbers if they are in the correct format of the type.

  • If the string is “true” or “false” (case insensitive), it can be converted to a Boolean using toBoolean(). Any value other than “true” will be a false Boolean.

Type Inference

  • In expressions involving variables of different datatypes, the widest type in the expression is inferred by the compiler as the type of the result.
    Double > Float > Long > Int > (Byte, Short)

  • The result of an expression involving Byte or Short variables is of the type Int (or an even larger type), unless explicitly casted.

  • Kotlin lets you create ranges of values using rangeTo() from the kotlin.ranges package, and its operator form ...

  • a..b is a range from a to b (inclusive), and in is a keyword used to check whether a value is within a range.

if (i in 1..5) {  // equivalent of 1 <= i && i <= 5
  • If you need to exclude the right border, you should subtract one from it:

val within = c in a..b - 1
// equivalent of a <= c && c < b
  • If you need to check that a value is not within a range, use !in:

val notWithin = 100 !in 10..99   // true
  • You can assign a range to a variable and use it later somewhere in the code:

val range = 1..5
print(3 in range)   // true
  • You can also use ranges of characters and strings (in dictionary order):

println('b' in 'a'..'c') // true
println("hello" in "he".."hi") // true
  • Integral type ranges can be iterated over using for loops:

for (i in 1..5) print(i)   // 12345
  • To iterate numbers in reverse order, use the downTo function instead of ..:

for (i in 5 downTo 1) print(i)   // 54321
  • To iterate over numbers with an arbitrary step, use the step function:

for (i in 1..10 step 2) {
    print(i)   // 13579
  • To iterate a number range which does not include its end element, use the until function:

  • A regex instance can be created using the toRegex() method of a String or by calling the Regex constructor:

val string = "ing"
val regex1 = string.toRegex()
val regex2 = Regex("ing")
// regex1 and regex2 represent the same regular expression
  • matches() method of a string returns true if the string is full match for the regex specified:

val regex = Regex("ing")
val string1 = "ing"
val string2 = "running"

println(string1.matches(regex))   // true
println(string2.matches(regex))   // false
  • The dot character (.) can match any character except a newline. A question mark (?) denotes that the preceding character is optional. A double backslash (\\) is used to escape special characters. A single backslash (\) is used to escape double quotes (").

  • To match \, the regexp is \\\\.

  • The Java Class Library provides a BigInteger class for processing very large numbers, limited only by the memory available. It is immutable.

import java.math.BigInteger

val number1 = BigInteger("52955871795228763416553091")   // initialized using constructor
val number2 = BigInteger.valueOf(1000000000)   // initialized from a Long value using the valueOf() method
val number3 = 1234.toBigInteger()   // initialized from an Int value using the toBigInteger() method

// Some constants defined in the BigInteger class:
val zero = BigInteger.ZERO // 0
val one = BigInteger.ONE   // 1
val ten = BigInteger.TEN   // 10
  • The divideAndRemainder() function returns an array consisting of the result of integer division and its remainder.

val (result, remainder) = oneHundredTen.divideAndRemainder(nine) // 12 and 2
  • The abs() function returns a new BigInteger whose value is the absolute value of the initial BigInteger. The gcd() function returns the greatest common divisor of two numbers.

val number = BigInteger("-1")
println(number.abs()) // 1

val twelve = BigInteger.valueOf(12)
val fifteen = BigInteger.valueOf(15)
println(twelve.gcd(fifteen)) // 3

Null Safety

  • To allow nulls, we have to declare a variable as nullable by defining the type of the variable as <type>?.

  • You can generally handle operations using nullable variables in three ways:
    • You can explicitly check whether the variable is null.

    var a: String? = "abc"
    val l = if (a != null) a.length else -1
    • Use the safe call operator, ?..

    val b: String? = null
    println(b?.length)      // returns b.length if b is not null, and null otherwise
    // the type of this expression is Int?

    Safe calls are useful in chains. For example, if Bob (Employee) may be assigned to a Department, that in turn may have another Employee as a department head, then to obtain the name of Bob’s department head (if any), we write:

    bob?.department?.head?.name     // returns null if any of the properties is null

    To perform an operation only for non-null values, you can use the safe call operator together with let:

    for (item in listWithNulls) {

    A safe call can also be placed on the left side of an assignment. If one of the receivers in the safe calls chain is null, the assignment is skipped, and the expression on the right is not evaluated at all:

    person?.department?.head = managersPool.getManager()

    We can also use the Elvis operator (?:) in place of an if-expression. The expression to the right of ?: is evaluated only if the left-hand side is null.

    val l = a?.length ?: -1
    // Equivalent to:
    // val l: Int = if (a != null) a.length else -1
    // Other examples:
    val parent = node.getParent() ?: return null
    • The not-null assertion operator (!!) can be used to convert any value to a non-null type and throw an exception if the value is null.

    val l = a!!.length
  • Regular casting may result in a ClassCastException if the object is not of the target type. You can use safe casts that return null if the attempt was unsuccessful:

var a: String? = "abc"
val n: Int? = a as? Int     // null, as the String can't be casted to an Int type
  • If you have a collection of elements of a nullable type and want to filter non-null elements, you can use filterNotNull():

val intList: List<Int> = nullableList.filterNotNull()     // [1, 2, 4]

  • Four spaces are used for indentation. Do not use tabs.
  • Omit semicolons (;) wherever possible, as they are optional.
  • Put spaces around binary operators, for example, a + b.
  • Put spaces between control flow keywords (if, when, for and while) and the corresponding opening parenthesis.
  • If a variable or function name is a single word, it should be in lowercase; if the name has multiple words, it should be in lowerCamelCase.
  • For curly braces, put the opening brace in the end of the line where the construct begins, and the closing brace on a separate line aligned horizontally with the opening construct.

if (elements != null) {
    for (element in elements) {
        // ...

Standard Input/Output

  • print(message: Any?) can be used to print the given message to the standard output stream.

  • println(message: Any?) prints the given message to the standard output stream along with a newline at the end.

  • readLine() reads a whole line from standard input and returns it as a String. The returned string can be casted to the required type using casting function like toInt() or toBoolean(). You can use two exclamation marks at the end of the function call to force a non-null return value.

val line = readLine()   // can be null
val line2 = readLine()!!    // not null; commonly used
  • A Java Scanner object can be used to read input:

import java.util.Scanner      // or import java.util.*

val scanner = Scanner(System.`in`)
val line = scanner.nextLine() // read a line
val integer = scanner.nextInt()   // read a number
val word = scanner.next()   // read a string

Functions and Lambda Expressions

  • A function definition in Kotlin looks like:

fun functionName(param1: Type1, param2: Type2, ...): ReturnType {
    // body of the function
    return result     // optional
// ReturnType is optional if the return type is Unit
  • If the function returns a single expression, you can avoid the curly braces:

fun hello() = print("Hello World")
fun isNegative(num: Int): Boolean = num < 0
// the return types of these functions can be inferred automatically
  • The main() function is the entry point in a Kotlin program.

fun main(args: Array<String>) {
    // body
// args is optional
  • Kotlin supports default arguments in function declarations and named arguments in function calls:

fun horizontalRule(symbol: Char = '-', count: Int = 10, end: Char = '\n') {
    for (i in 1..count) {

fun main() {
    horizontalRule()                // ----------
    horizontalRule('_', end = '?')  // __________?
  • The default value for a parameter of a function can also be another named argument, or a function:

fun sum(a: Int, b: Int = a) = a + b
  • Kotlin uses the call stack (execution stack) of the JVM to store information about functions that are being executed. Each function and its associated data (like function address, argument references and local variables) is stored as a stack frame in the stack. A StackOverflowError occurs when the number function invocations exhaust the memory available to the stack.

  • Functions are first-class citizens in Kotlin. They can be stored in variables, and passed to or returned by other functions.

  • The type of a function is given as:
    (types of parameters, comma separated) -> return type of the function

// Type is:
// (Int, Int) -> Int

fun hello() = print("Hello World")
// Type is:
// () -> Unit
  • Reference to a function can be obtained by prefixing a double colon (::) to the function name.

var newSum = ::sum
// newSum(1, 2) will return 3
  • The filter() method of String or collections can accept references to other functions to act as the filtering criteria.

  • Anonymous functions in Kotlin are of the form fun(arguments): ReturnType { body }

  • Lambda expressions in Kotlin are of the form { arguments -> body }.
    If the lambda doesn’t have arguments, it’s written in the form { body }.

  • When the lambda is the last argument to a function, it can be placed outside the parenthesis. If the function has no other arguments other than the lambda, you can omit the parenthesis altogether. If there is only a single argument for the lambda, it can be used to refer to the parameter rather than assigning a name to it.

val someText = "L-o-r-e-m I-p-s-u-m"

print(   someText.filter({ ch -> ch != '-' })    )    // Lorem Ipsum
print(   someText.filter() { ch -> ch != '-' }   )    // Lorem Ipsum
print(   someText.filter { ch -> ch != '-' }     )    // Lorem Ipsum
print(   someText.filter { it != '-' }           )    // Lorem Ipsum
  • If the lambda has multiple lines of code, its last line is treated as the return value. The return keyword is not required in this case.

  • If you use return in a lambda expression, a non-local return happens to the nearest enclosing function.

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return              // non-local return directly to the caller of foo()
    println("this point is unreachable")
  • To return just from a lambda expression and not the enclosing function, you need to use a fully qualified return statement.

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach [email protected]{
        if (it == 3) return@lit           // local return to the caller of the lambda, the forEach loop
    print(" done with explicit label")

fun bar() {
        if (it == 3) return@forEach       // local return to the caller of the lambda, the forEach loop
    print(" done with implicit label")
  • A return statement in an anonymous function will return from the anonymous function itself.

fun foo() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return            // local return to the caller of the anonymous function, the forEach loop
    print(" done with anonymous function")
  • The variables and values visible where the lambda is created are also visible inside the lambda, i.e. lambda captures variables. So if a variable is changed inside the lambda, the changes are also reflected outside it.

fun placeArgument(value: Int, f: (Int, Int) -> Int): (Int) -> Int {
    return { i -> f(value, i) }

val mul = { a: Int, b: Int -> a * b }
val double = placeArgument(2, mul)
print(double(5))      // 10

Standard Library

  • The Math (inherited from Java) and kotlin.math libraries contains implementation of common mathematical functions and constants.

val sqrt = Math.sqrt(2.0)   // 1.4142...
  • Random numbers can be generated using the Random class in the kotlin.random package.

import kotlin.random.Random

fun main() {
    println( Random.nextInt() )       // generates a random Int number
    println( Random.nextLong() )      // generates a random Long number
    println( Random.nextFloat() )     // generates a random Float number between 0 (inclusive) and 1.0 (exclusive)
    println( Random.nextDouble() )    // generates a random Double number between 0 (inclusive) and 1.0 (exclusive)
    println( Random.nextInt(10) )     // generates a non-negative Int value less than 10
    println( Random.nextInt(1, 10) )  // generates an Int value between 1 (inclusive) and 10 (exclusive)
    // ranges can be specified for all these functions except nextFloat()
  • You can set the seed for the pseudorandom number generator using the Random() class constructor.

val generator = Random(42)      // setting the seed 42
for (i in 0..4) {
    print(generator.nextInt(10).toString() + " ")     // "3 0 1 2 1 " will always be the sequence generated for this seed if the same Kotlin runtime and architecture is used
  • A generator initialized using Random.Default will have a different seed each time it is used.

  • Kotlin supports the following native arrays for primitive types: IntArray, LongArray, DoubleArray, FloatArray, CharArray, ShortArray, ByteArray and BooleanArray. There is no StringArray.

  • To create an array of a specified type, pass the elements as parameters to functions like intArrayOf(), charArrayOf() and booleanArrayOf(). To initialize an array with a single value, use a lambda expression along with the type constructor.

val numbers1 = intArrayOf(1, 2, 3, 4, 5)      // Array<Int>: { 1, 2, 3, 4, 5 }
println(numbers.joinToString())               // 1, 2, 3, 4, 5

val numbers2 = IntArray(5)                    // { 0, 0, 0, 0, 0 }
val numbers3 = IntArray(5) {1}                // { 1, 1, 1, 1, 1 }
  • You cannot change the size of an array, but you can modify its elements.

  • The size of an array can be obtained using the size property.

val numbers = intArrayOf(1, 2, 3, 4, 5)
println(numbers.size)       // 5
  • Arrays also have the first(), last() and lastIndex() methods, and it works in the same way it does for String.

  • Arrays can be compared using the contentEquals() method, as == only compares the references and not the contents of the object.

val numbers1 = intArrayOf(1, 2, 3, 4)
val numbers2 = intArrayOf(1, 2, 3, 4)

println(numbers1.contentEquals(numbers2))     // true
println(numbers1 == numbers2)                 // false
  • The Array<T> class lets you create an array of any object. The arrayOf() and emptyArray() functions can be used to create an Array.

val array1 = arrayOf("Hello", "World")
val array2 = arrayOf<String>("Hello", "World")      // if you want to enforce the type
val array3 = emptyArray<String>()
  • The joinToString() method returns a String containing the elements of the array, separated using commas. The contentEquals() method can be used to compare the Array with another Array.

  • The size of an array can be changed (by adding or removing elements) only if it was declared using var, and not val. However, you can change the elements in both cases.

  • Arrays can be nested to create multidimensional arrays. The nested arrays can even be of different types.

val array = arrayOf(
    arrayOf(1, 2),
    arrayOf(3, 4, 5))
  • The contentDeepToString() method can be used to get the entire content of a multidimensional array as a single String.

Control Flow Statements

  • In Kotlin, if is also treated as an expression, and not just a statement. It can return the result of some computation, by specifying the result as the last expression in the body. If if is used as an expression, it must have an else branch.

val max = if (a > b) {
    println("a wins!")
} else {
    println("b wins!")
  • The braces can be omitted if the body has only one statement.

println( if (a == b) "a equal b"
         else if (a > b) "a is greater than b"
         else "a is less than b" )
  • The when construct is the alternative to the switch-case statement found in many languages. The else keyword specifies the default (fallback) argument for the construct. You can use multiple statements in a branch by enclosing them in curly braces. They can also be used as expressions, and the else branch is required in such cases.

when (alphabet) {
        "a", "A" -> println("Alpha")
        "b", "B" -> println("Beta")
        "c" -> { println("Gamma")
                 alphabet = "C"
        else -> println("Unknown")
  • The branch conditions of a when construct can also be expressions. It can also be used without an argument; in this case, the branch conditions are evaluated as boolean expressions.

val a = 5
val b = 6
val c = 11

println(when (c) {
        a + b -> "$c equals $a plus $b"
        a - b -> "$c equals $a minus $b"
        a * b -> "$c equals $a times $b"
        else -> "We do not know how to calculate $c"
        })                                            // "11 equals 5 plus 6"
when (c) {
        in 0..10 -> println("c is between 0 and 10 (inclusive).")
        else -> println("c is not between 0 and 10.")
  • The repeat block simply executes its body over and over again for the specified number of times.

import java.util.*

val scanner = Scanner(System.`in`)
val n = 10
val sum = 0

repeat(n) {
        val num = scanner.nextInt()
        sum += num
  • A for loop is used to iterate through ranges, arrays or collections of elements.

for (i in 1..4) {
  • Kotlin supports the standard while and do..while loops. The break and continue statements also work as expected.

  • Any expression in Kotlin may be marked with a label. Labels have the form of an identifier followed by the @ sign. You can use break, continue and return statements using these labels.

    for (j in 1..100) {
        if (i == 10 && j == 10) break@loop      // breaks out from both loops

fun foo() {                                     // prints "1245"
        if (it == 3) return@forEach // local return to the forEach loop

fun foobar() {                                  // prints "12"
    run [email protected]{
            if (it == 3) return@loop // non-local return from the lambda passed to run

Object Oriented Programming

  • A class is defined using the class keyword. If the body of the class is empty, the curly braces can be omitted.

class ClassName {
  // class properties and methods

val object = ClassName()
  • The default values of the properties can be specified in the class definition itself. The properties can be accessed by using the object.property format.

class Solid {
  var color = "red"
  var count = 10
  var shape = "sphere"

val object = Solid()
println(object.shape)     // sphere
  • A class in Kotlin has one primary constructor, and zero or more secondary constructors. The primary constructor is a part of the class header, and does not have to be defined separately. Optionally, the primary constructor can also take parameters.

class Person(name: String) { /*...*/ }
// Same as:
// class Person constructor(name: String) { /*...*/ }
  • Any initialization code for the primary constructor has to be put in one or more init blocks. These init blocks are executed in the order in which they appear.

class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)

    init {
        println("First initializer block that prints ${name}")

    val secondProperty = "Second property: ${name.length}".also(::println)

    init {
        println("Second initializer block that prints ${name.length}")
  • The parameters passed to the primary constructor can be used as class properties by adding val or var keywords to the parameters list.

class Name(val firstName: String, val lastName: String)     // example of a data class, used to store structured data
  • The primary constructor also takes default values in the arguments list.

class Solid(val shape = "sphere", val color = "red") { /*...*/ }
val object = Solid(color = "blue")
  • Class methods are called member functions in Kotlin. They are defined inside the class definition block. The this keyword can be used to refer to the current instance.

class Color(var color = "red") {
  fun printColor() {
    print(this.color)     // you can omit the 'this' keyword if the property name is unique

val obj = Color("green")
obj.printColor()      // prints "green"
  • When you access a property, a getter function is invoked implicitly. Similarly, a setter function is invoked when the value of a property is changed. Each property has their own getter and setter functions. They are automatically defined by the compiler, but you can define custom functions if required. Inside the getter and setter function, the keyword field has to be used in place of the actual property name to avoid an infinite recursive call of getter/setter functions.

class Person {
    var name: String = "John"
        get() = field
        set(value) {
          print("Changed name from $field to $value.")
          field = value

val guy = Person()
guy.name = "Ron"      // prints "Changed name from John to Ron"
  • If a class is to be inherited (extended), it has to be declared with the open keyword. We can pass parameters to the constructor of the parent class, if required.

open class Person(var name: String, var age: Int = 25)

class Employee(name: String, dept: String) : Person(name) {
    var department = dept
  • Any function that accepts a parent class also accepts a child class as its parameter.

  • To override a function from the parent class in a child class, the open modifier has to be used in the function definition in the parent class, and the override modifier has to be used in the function definition in the child class. An overridden method is automatically open to all subclasses (if any). The final modifier can be used to close such implicitly open functions. Overriding properties works in a similar way.

open class Shape {
    open val vertices: Int = 0

class Rectangle : Shape() {
    final override val vertices = 4
  • Code in a derived class can call its superclass functions and property accessors implementations using the super keyword.

open class Rectangle {
    open fun draw() { println("Drawing a rectangle") }

class FilledRectangle : Rectangle() {
    override fun draw() {
        println("Filling the rectangle")
  • Secondary constructors are declared as constructor(). A class can have more than one secondary constructors, provided they all have unique function signatures.

class Person {
    var children: MutableList<Person> = mutableListOf()
    constructor(parent: Person) {
  • If the class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor(s). The this keyword can be used to delegate to another constructor of the same class. Delegation to the primary constructor happens as the first statement of a secondary constructor, so the code in init blocks and property initializers is executed before the secondary constructor body.

class Person(val name: String) {
    var children: MutableList<Person> = mutableListOf()
    init {
        println("Initializing..")     // always runs before the secondary constructor
  • A singleton class is a special class with a only single instance globally. Singletons are implemented in Kotlin by using object declarations. The singleton is declared like a regular class declaration, but with the keyword object in place of class. Such classes doesn’t need instantiation, and can be accessed directly using the class name.

object President {
  val name = "Abraham Lincoln"
  fun printMsg() {
    println("$name was a former US President.")

  • Classes can be nested. As a singleton is also a special type of class, objects declarations can also be nested in class or object declarations.

  • Extensions are used to extend a class with new functionality without having to inherit from the class. You can declare methods and properties for a class without modifying the actual class declaration. To declare an extension, we prefix its name with the receiver type (the class being extended). Extensions do not actually modify the classes being extended, and are resolved statically.

    this[index1] = this[index2]
    this[index2] = tmp

val list = mutableListOf(1, 2, 3)
list.swap(0, 2) // [3, 2, 1]
  • If an extension for a class is defined with the same name (and signature) as a member, the member always wins. However, functions can be overloaded by using a different signature.

class Example {

fun Example.printFunctionType() = println("Extension function")

Example().printFunctionType()     // Class method
  • Extensions can also be defined with a nullable receiver type.

fun Any?.toString(): String {
    if (this == null) return "null"
    // resolves to the member function of the Any class
    return toString()
  • Extension properties can have getters and setters, but cannot have initializers.

  val <T> List<T>.lastIndex: Int
    get() = size - 1
  • The toString() method of classes are invoked implicitly by when you try to print them. You can override the toString() method of a class to change the default behavior (which is a string of the form <class_name>@). This modified function is inherited by the child classes, if any.

open class Toy(val type: String = "ball", val color: String = "blue") {
  override fun toString(): String {
    return "$color $type"

class ToyOwner(val name: String, type: String = "ball", color: String = "blue") : Toy(type, color) {
  override fun toString(): String {
    return "${name}'s ${super.toString()}"

val blueBall = ToyOwner("John")
print(blueBall)   // John's blue ball
  • An object declaration inside a class can be marked with the companion keyword. Members of the companion object can be called by using simply the class name as the qualifier. The name of the companion object can be omitted, in which case the name Companion will be automatically.

class SampleClass {
    companion object {
        fun create(): SampleClass = SampleClass()

val instance1 = SampleClass.create()
val instance2 = SampleClass.Companion.create()
// both function calls refer to the same function, and creates different instances of the class
  • Properties from the outer class will shadow the properties of the companion if they have the same name. Only one companion object can be created for a class. A companion class cannot be nested inside another companion class or object declaration.

  • The enum keyword is used to create enumeration classes.

enum class Rainbow {
  • Enum classes can be used to store multiple parameters per member, and even add member functions.

enum class Rainbow(val color: String, val rgb: String) {
    RED("Red", "#FF0000"),
    ORANGE("Orange", "#FF7F00"),
    YELLOW("Yellow", "#FFFF00"),
    GREEN("Green", "#00FF00"),
    BLUE("Blue", "#0000FF"),
    INDIGO("Indigo", "#4B0082"),
    VIOLET("Violet", "#8B00FF");

    fun printFullInfo() {
        println("Color: $color --- RGB: $rgb")

val rgb = Rainbow.RED.rgb
  • Enum classes also contain some methods and properties implicitly defined by Kotlin.

val color: Rainbow = Rainbow.BLUE
println(color.name)     // returns the enum instance's name, "BLUE"
println(color.ordinal)      // returns the postion (index) of the instance in the class declaration, 4
fun isRainbowColor(color: String) : Boolean {
    for (enum in Rainbow.values()) {      // returrns a list of instances in the enum class
        if (color.toUpperCase() == enum.name) return true
    return false

println(isRainbowColor("Pink"))     // false
  • Data classes declared with the modifier data is used to store data in an organized manner. These classes automatically support methods like equals(), hashCode(), toString() and copy(). However, such built-in methods only consider the properties listed in the constructor, and ignores any properties found in the body of the class. All the methods except copy() can be overridden if required.

data class Toy(var type = "Ball", var color = "Blue")

val blueBall = Toy()
val redBall = blueBall.copy(color = "Red")
  • Data classes can be unpacked, or destructured. A destructuring declaration uses a componentN() operator that returns the n-th element in the data class.

val blueBall = Toy()
val (toyType, toyColor) = blueBall
// Same as:
// val toyType = blueBall.component1()
// val toyColor = blueBall.component2()

println(toyType)      // Ball
println(toyColor)     // Blue
  • Regular classes can also be destructured if you explicitly define componentN() operators.

    operator fun component1(): String = type
    operator fun component2(): String = color
  • Destructuring also works with arrays. If there are less variables than the size of the array, it will skip the remaining elements of the array. If there are more variables, the expression will result in an error. If you don’t need a variable in the destructuring declaration, you can place an underscore instead of its name.

  • The following properties and methods are supported by all the standard collections in Kotlin:

    • size
    • contains(element) → checks if element is in the collection
    • containsAll(col) → checks whether all the elements in the collection col is in the current collection
    • isEmpty()
    • joinToString() returns a string consisting of the elements of the collection.
    • indexOf(element) returns the index of the first occurrence of element in the collection, and -1 if element is not present in the collection.
  • Mutable collections have some more common methods:

    • clear() removes all the elements in the collection
    • remove(element) removes the first occurrence of element
    • removeAll(col) removes all elements of the collection col from the current collection
  • List<T> stores elements in a specified order and provides indexed access to them. A List can contain duplicate elements, even null.

val numbers = listOf("one", "two", "three", "four")
val empty = emptyList<String>()     // to initialize an empty list

println("Number of elements: ${numbers.size}")
println("Third element: ${numbers.get(2)}")
println("Fourth element: ${numbers[3]}")
println("Index of element \"two\" ${numbers.indexOf("two")}")
  • A MutableList<T> is a mutable List, i.e supports adding or removing elements. A List can be converted to a MutableList using the toMutableList() method of a List.

val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)    // 1, 2, 3, 4, 5
numbers.removeAt(1)   // 1, 3, 4, 5
numbers[0] = 0    // 0, 3, 4, 5
numbers.shuffle()   // list is shuffled in a random order
  • A Set<T> is used an unordered collection of unique elements. Even null can occur only once in a Set. Two sets are equal if they have the same size, and for each element of a set there is an equal element in the other set. The default implementation of a Set is a LinkedHashSet, which remembers the order of insertion of elements. So it also supports methods like first() and last().

val numbers = setOf(1, 2, 3, 4)

if (numbers.contains(1)) println("1 is in the set")

val numbersBackwards = setOf(4, 3, 2, 1)
println("${numbers == numbersBackwards}")
  • A MutableSet allows you to add or remove values.

val empty = mutableSetOf<Int>()     // declare an empty mutable set for Int elements
  • Map<K, V> stores key-value (KV) pairs. The keys in a Map should be unique. Two maps containing the equal pairs are equal regardless of the order in which the pairs are found in the maps.

val numbersMap = mapOf<String, Int>("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)     // the type specification can be omitted as it is automatically inferred
println("All keys: ${numbersMap.keys}")
println("All values: ${numbersMap.values}")
if ("key2" in numbersMap) println("Value of \"key2\": ${numbersMap["key2"]}")
if (1 in numbersMap.values) println("The value 1 is in the map")
if (numbersMap.containsValue(1)) println("The value 1 is in the map") // same as previous
  • A MutableMap allows you to add new key-value pairs and update existing ones.

val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap.put("three", 3)
numbersMap["one"] = 11
println(numbersMap)     // {one=11, two=2, three=3}
numbersMap.remove("four")     // nothing happens
numbersMap.remove("three", 4)     // removes the pair only if the value associated with "three" is 4
println(numbersMap.containsValue(3))      // true
println(numbersMap.containsKey(3))      // false
  • Collections support iteration. When iterating over maps, a pair of values is returned in each iteration, which can be destructured into two separate variables.

  • A description of all the properties and methods supported by lists, mutable lists, sets, mutable sets, maps and mutable maps can be found in the official documentation.

  • You can throw exceptions using the throw keyword.

throw ArithmeticException
  • The Exception class is used to create custom exceptions.

val customException = Exception("A custom error message.")
throw customException

// Same as:
// throw Exception("A custom error message.")
  • Kotlin supports try-catch blocks. They can have multiple handlers (catch blocks) if required. The message property stores the error message related to an Exception. When an exception occurs in the try block, the suitable handler is determined by trying to match the exception types from the first catch block to the last. So specialized handlers like IOException should come before general handlers like Exception (which can catch every type of exception). After the exception is handled, code execution resumes from the line immediately after the try-catch block.

try {
    print(10 / 0)
catch (e: IOException) {
    // handles IOException and its subtypes
catch (e: Exception) {
    // handles all subtypes of Exception
    println(e.message)      // "/ by zero"
  • A finally block is executed irrespective of whether an exception was encounter in a try or catch block.

try {
    // code that may throw an exception
catch (e: Exception) {
    // exception handler
finally {
    // always executed
  • A try-catch block can also be used as an expression in Kotlin.

val number: Int = try { "abc".toInt() } catch (e: NumberFormatException) { 0 }
println(number)     // 0

Working With Files

  • Files are handled using the File class from the java.io package. A File object contains a pointer to the specified file. When a method (except write methods) is called and the file does not exist, and a NoSuchFileException is thrown.

  • The readText() method returns the entire contents of the file as a String.

import java.io.File

val file = File("file.txt")       // file is not opened, only a reference to the file is returned
val content = file.readText()     // file is opened and closed automatically by the method
print(content)                    // entire content of the text file is displayed
  • The readLines() method returns a List with each line of the file as an element of the list.

  • The readBytes() method returns the entire content of the file as a byte array.

  • The forEachLine() method executes an action for each line in the file. This is recommended for very large files, as directly trying to read the entire file in one go may exhaust the system memory.

val fileName = "file.txt"
File(fileName).forEachLine { println(it) }
  • The writeText() method is used to write a String to file. If the file does not exists, it is created automatically. If the file already exists, its contents are overwritten.

  • The appendText() method is used to append a String to an existing file.

  • The writeBytes() and appendBytes() methods are used to write a ByteArray to file.

  • The length() method returns the number of characters in the file.

  • The exists() method of the File class can be used to check whether a file exists.

  • A list of all methods supported by the File class can be found in the official documentation.

Basic Syntax – Kotlin Official Documentation
Kotlin Programming Language Reference – Kotlin Official Documentation
NOTE: A lot of code samples have been taken directly from the official documentations.

Learn Kotlin

  • JetBrains Academy has a Kotlin track that helps you learn by working on a project in Kotlin. The course is current in a public beta phase, and available for free at the time of writing.
  • Kotlin Koans is great way for Java developers to learn Kotlin, by working on a curated series of exercises in Kotlin."""

```json
{
  "format": {
    "score": 3,
    "justification": "The text is well-structured and follows a professional format with clear headings and sections. It is easy to follow and organized effectively."
  },
  "voice": {
    "score": 1,
    "justification": "The text has a clear, distinct authorial voice, particularly evident in its technical style and the use of programming-specific terminology."
  },
  "knowledge_density": {
    "score": 3,
    "justification": "The text provides a high density of information, covering a wide range of Kotlin programming concepts in depth and detail."
  },
  "diversity": {
    "score": 1,
    "justification": "The text focuses primarily on Kotlin programming concepts and lacks niche or specialized knowledge, hence it scores low on diversity."
  }
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""Central Australia

The Central Australia region is the geographical centre of Australia.

Desert land covers 600,000 square kilometres and 40% of the NT.

The Central Australia region contributes an estimated 18% ($2.9 billion) to the NT gross state product.

Alice Springs, the second largest town in the NT, with a population of roughly 28,000, services a total regional population of 41,000.

Alice Springs is the major economic, business and service hub for the region, and also services parts of South Australia, Western Australia and Queensland.

The economy is sustained by mining, tourism and primary industries and is underpinned by government funding for regional service delivery and defence.

A large percentage of the Central Australia region’s population live in outlying communities including the Yulara township, which provides accommodation and services for the tourism industry at Uluru–Kata Tjuta National Park.

Yulara's population of just over 1,000 people is increased by visitor numbers to around 300,000 each year.

Other major remote centres in the Central Australia region include Ntaria, Yuendumu and Papunya, with the rest of the population widely spread across the region in smaller communities, outstations, pastoral properties and mining operations.

These residents depend on Alice Springs for supplies and essential services.

Last updated: 24 September 2021

Give feedback about this page.

Share this page:

URL copied!"""

```json
{
  "format": {"score": 2, "justification": "The text is mostly well-structured with clear paragraphs, but there are some minor formatting issues like the extra 'Last updated:' and 'Share this page:' lines which are not necessary for the main content."},
  "voice": {"score": 1, "justification": "The text has a factual, informative tone typical of a reference or descriptive article, lacking a distinct authorial style or voice."},
  "knowledge_density": {"score": 2, "justification": "The text provides specific details about Central Australia's geography, economy, and population, though some information like population figures could be more contextually linked to broader trends."},
  "diversity": {"score": 1, "justification": "The content covers general aspects of Central Australia's geography, demographics, and economy, which are common knowledge and not niche or specialized."}
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""MERIDA Yucatan (Times Media Mexico) – Whoever visits Yucatan soon notices the unique elements that differentiate it from the Mexican Republic’s other states. Perhaps, Campeche and Quintana Roo’s neighboring states, which once formed a single entity and have a shared history. The Yucatan Mayan language gives the Spanish spoken in Yucatan an emphatic and robust accent that is quickly identifiable. Likewise, it mixes many Mayan words with the Spanish spoken in this state, the culture, music, gastronomy, and in general, the way of being of the Yucatan, which is exotic even for our compatriots.

On one occasion, many years ago, in a bohemian talk by friends, between drinks of aged rum, someone mentioned that in Mexico, there are two kinds of Mexicans: the Mexicans, worth the redundancy, and the Yucatecans.
Historically, the Yucatan developed, to some extent, apart from the rest of the country.

During the colonial era, it was General Captaincy. That is, the Governor and General Capital were directly named by the King of Spain. Therefore, both politically and militarily, they depended and were directly accountable to the Spanish crown; their territory, at some point, included, besides the mentioned and current states of Yucatan, Campeche, and Quintana Roo, also Tabasco, Belize, and the Guatemalan Petén. Only, in the judicial field, the Yucatecans had to resort to the Royal Court of New Spain or the Royal Court of Guatemala.

Coupled with the peninsula’s geographic location and its dense forests and rainforests, it made communications easier by sea than by land. Yucatan was isolated from the rest of the “New Spain” and Mexico once independence from Spain was obtained.

All these circumstances have shaped the Yucatecan culture. However, it can be said that the current Yucatecan is a consequence of the syncretism of the Mayas and the Spanish. Other countries and cultures have contributed their grain of sand in the conformation of our identity; influences such as the Lebanese, European, Caribbean, and even Asian have influenced the cultural confirmation of this part of the Mexican nation; so much so that even the famous American Chef Ricky Bayless specialized in Mexican food, in his program entitled “Mexico: One Plate at a time”, in its 11th season, is dedicated to the gastronomy of this region of the country and indicates the following in its official page: “For the 11th season of Chef Rick Bayless’ highly-rated cooking and travel show, we’re taking our viewers on a journey through a different Mexico, to the Yucatan Peninsula.”

Between Cuba and Yucatan there has been a close historical relationship, even since pre-Columbian times, not only because the island was the gateway and therefore communication of Spain with its American domains, but also by the geographical proximity to our peninsula, separated by the Yucatan channel and the geographical arrangement of both, the poet Salvador Diaz Miron expressed: “Like two hands that were together and still want to shake each other”; with an identical climate, Doctor Eduardo Urzaiz Rodriguez, points out in one of the works that serve as a source for this article, that it is one more Antilla that, by the whim of Geology, remained attached to the Continent.

During the time in which Yucatan separated from Mexico for opposition to the centralism established by Antonio López de Santa Anna, in the middle of 1847, the Mayan people’s rebellion against the Creole and mestizo oppression broke out in the east of the state, the Mayan hosts were devastating the towns, until practically arriving at the doors of the city of Merida, the government’s resources were exhausted and the situation was desperate, when unexpected help arrived from Cuba, on March 9, 1848, The Spanish war Churruca, the brigantine schooner Juanita and the war corvette Luisa Fernanda arrived at the port of Sisal with a cargo of 2000 useful rifles with their bayonets, 200 cavalry sabers, 2 12-pound mountain howitzers and 200 quintals of gunpowder, that were of great help and that served to raise the spirits of the Yucatecans and, although the support came from the Spanish authorities on the island, it left a debt of gratitude in the hearts of the Yucatecans, which was later taken advantage of by the Cuban emigrants.

To be continued…

Miguel Fernández-Montilla Cervera
For The Yucatán Times

Miguel Fernández-Montilla Cervera is a Yucatecan  lawyer, specialist in labor law, and an enthusiast of Yucatan’s history. He has hosted the program “El buho de la noche” (The Night Owl) which deals with historical issues and anecdotes of the Yucatan.

more recommended stories"""

```json
{
  "format": {"score": 3, "justification": "The text sample is well-structured with clear paragraphs and appropriate sectioning. There are no formatting issues, and the writing flows naturally from one idea to the next."},
  "voice": {"score": 1, "justification": "The text maintains a professional and informative tone, with a distinct voice that reflects the author's expertise in Yucatan's history and culture."},
  "knowledge_density": {"score": 3, "justification": "The text provides rich, informative content with historical context, cultural insights, and specific details about Yucatan's unique characteristics and relationships with other regions."},
  "diversity": {"score": 1, "justification": "The content covers various aspects of Yucatan's culture and history, but it remains within the realm of general knowledge and does not delve into highly specialized or rare topics."}
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""Do you have now, or have you ever had a child who engaged in challenging behavior?

If so, you may have been given or asked to participate in the creation of a behavior plan.

IDEA states that a behavior plan is based on a functional behavioral assessment.

A functional behavioral assessment is considered an evaluation that, through data collection and observations hypothesizes the function of behavior. Once you have a data-driven hypothesis, a behavior plan (if necessary) would be created, which should include strategies and interventions that address the behaviors and their functions.

There is a function behind all behavior.

Take a second to think about your own behavior. Do you bite your nails, do you play on Facebook for a few minutes instead of finishing that report? I could go on and on, but you probably get where I am going.

When we think about our students or children, understanding the function of their behavior may help us respond in a way that creates change and not more or different challenging behaviors.

Interesting Functions Of Behavior;

There are four types of function in regards to behavior;

Tired Of The Endless Search For Answers?

Schedule A Free Consultation With A Special Education Expert Today!
Free Consultation
  • Sensory/Automatic
  • Escape
  • Attention
  • Tangible

Let’s take a more in-depth look into each behavior and some examples of each.

This function is sometimes referred to as self-stimulatory. The behaviors are not dependent on anything other than the behavior itself. The behavior itself is reinforcing to the person.

Some examples of Sensory behaviors would be: repetitive body motions such as, but not limited to- hand flapping, leg shaking, spit play, chewing on fingers, nail-biting and could also include some self-injurious behaviors.

Behaviors with an escape function are meant to do just that, escape from whatever has been presented to the person immediately before the behaviors. To stop or avoid something is what is reinforcing.

Some examples of Escape/Avoidance behaviors would be: Aggression, spitting, (to get people to leave them alone), running away, crying, whining, masturbation and self-injurious behavior.

Think about it like this – there’s a child in the classroom who was given an assignment and does not immediately start it. Instead, he throws his pencil and gets up to roam the room. This is an example of escape behavior that has been reinforced.

Behaviors with an attention function are those that are done to elicit attention.

Attention can be positive or negative. Sometimes, attention is so reinforcing that it can be negative (ex. behavioral correction) or positive (ex. praise). Any attention that maintains the behavior is reinforcing.

Some examples of Attention behaviors would be: calling out in class, nose picking, aggression, elopement, and unsafe climbing.

Think about it like this – a child is climbing on a bookshelf in a classroom. Every single time the teacher walks over, tells him to get down and then physically pulls him down, the child goes back to the activity they should have been doing. This is an example of attention-seeking behavior that has been reinforced.

Behaviors with a tangible function are to obtain an object or item. This function is pretty straightforward that a person engages in a behavior to get something.

Some examples of Tangible behaviors would be: yelling, screaming, and aggression.

Think about it like this – You’re in a store with your child at checkout. There are rows of candy bars. Your child starts screaming for one. You give it to them to stop the screaming. This is an example of tangible behavior that was reinforced.

These examples of behaviors are not an end-all list, but instead just collection of some behaviors you may encounter. Each person and their behavior is unique and must be treated as such.

FBA’s (Functional Behavioral Assessment) and BIP’s (Behavior Intervention Plan) should be individualized to the person they are about.

As a teacher and a special education tutor, I am constantly aware of my actions and how they may be affecting children around me. As you develop a greater knowledge in this area, you will help your child develop in a way that truly maximizes their potential (and decreases your stress level substantially)!

Nicole Adamski, MA

Nicole Adamski, MA

Nicole Adamski, MA

Nicole Adamski, MA

Leave a Reply"""

```json
{
  "format": {"score": 2, "justification": "The text is mostly well-structured with clear headings and subheadings, but there are some minor formatting issues like repetitive author names and repeated mentions of 'Nicole Adamski, MA' which could be better organized."},
  "voice": {"score": 1, "justification": "The author demonstrates a clear, authoritative tone, especially in providing guidance on behavior plans and assessments. However, it lacks a distinct, distinctive style."},
  "knowledge_density": {"score": 2, "justification": "The text provides substantial, informative content on the topic of functional behavioral assessments and behavior plans, though some sections repeat similar ideas about behavior functions."},
  "diversity": {"score": 1, "justification": "The text covers general topics related to behavior and education but lacks niche or specialized content. Most information is common knowledge in this domain."}
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""Design Approach to Intercom Public Address (PA) System

A design approach to a PA system encompasses the available technologies and a project-specific project-specific engineered layout. This requires a review of the plan drawings to confirm coverage/functionality and a load calculation of the design circuits thus assuring that the expected sound level is realized at each location.

When reviewing the plan drawings, it is important to understand the differences in performance provided by the different speaker types. The more commonly used speakers are speaker/transformer/baffle assemblies, usually a ceiling mount unit, and the horn speaker type also called a loudspeaker. The horn speaker is normally applied to common areas with high occupancy and outdoor use. Two major differences in performance can be seen in the speakers. Possibly the more important difference is in response rate; the frequency response in the normal speech range is significantly better on the ceiling mount type speaker. This basically means that typical announcements come thru as a more intelligible speech pattern. The other major difference is in the audio output performance. In this, the horn speaker can produce up to 15 watts of audio power while the ceiling mount speaker can produce a maximum of 5 watts. The power rating on the speakers translates directly to sound levels where more power means louder sound.

As noted, the typical mounting of the two-general type of speakers differs. The more common ceiling type speaker is offered in a 2x2 drop-in ceiling tile and also as a pendant back-can configuration for mounting in hard ceilings; either recessed in the ceiling or suspended on a conduit box. The horn speaker is often recessed into a wall but does have a surface mount option. The horn speaker is not easily ceiling mounted.

Once the type of speakers in the layout is identified, the sound level has to be established. Because the sound level is directly related to power, louder overall building requirements mean more power must be made available thru the PA system. The typical measurement for sound pressure is the dB scale. The OSHA Sound Level chart is used to establish a baseline with the understanding that the scale is for sustained sound levels and not short announcements.

A typical scale is as follows:

Allowable exposure to the levels are as follows:

  From the above, a value of 80 dB is used for a typical classroom, 91 dB for hallways, and 105 dB for horn speakers. After an audible power value is placed on the speakers, a power matrix is created which represents the limits that a PA output card and amplifiers can supply as well as defining the maximum speakers that can be "strung" together…placed in one common circuit. An example of the power matrix is shown below:

 This chart represents a PA system with 18 output cards, each card having 25 output ports and a maximum capacity of 50 watts per card. Note that this system also includes an RTU; a large capacity output module.

Two considerations are accounted for when assigning output ports:

  • Maintaining the load per card at below 80%, if possible, but always below 100%. Further evaluation is given to those cards that exceed 80%
  • Grouping of PA zones/areas of the building within the same output cards

Load assignments to ports are based on the number of speakers in each circuit. This is symbolized by riser diagrams. The riser diagram is a representation of how an output channel will provide power from the port thru each terminal block down to the speaker.

An example is shown below:

Once the power assignments are allocated, the total power (watts) can be calculated, and thus the number of amplifiers required to meet the listed load.

It is important to note that each output port has a maximum capacity. As such, the matrix prevents overloading any one port, the individual card or reaching the limits of assigned amplifiers to respective cards. High loads can be assigned to high output ports and, where needed, space can be made available for future expansion by assigning expected values to the associated ports.

Fieldwork is also simplified as the speaker assignments are engineered to the respective terminal blocks. An example of the expected wiring is shown below.

With this approach, field wiring, testing, and troubleshooting can be traced down to specific circuits thus eliminating any guesswork as to where the tie point might be.

The end result is a fully functional system meeting the intended sound levels of each area.

Short Circuit Current Ratings for UL 508A Industri...
BLTI Becomes Value Added Reseller for Samsara - Wi...
"""

```json
{
  "format": {
    "score": 2,
    "justification": "The text is well-structured with clear headings and subheadings, but there are minor formatting inconsistencies, such as spacing between paragraphs and inconsistent use of bullet points."
  },
  "voice": {
    "score": 1,
    "justification": "The text maintains a professional and technical tone, though it lacks a distinct authorial voice or unique style."
  },
  "knowledge_density": {
    "score": 2,
    "justification": "The text provides substantial technical information about PA system design, including speaker types, sound level calculations, and power matrix considerations."
  },
  "diversity": {
    "score": 1,
    "justification": "The content primarily covers technical aspects of PA systems with limited diversity, focusing on common speaker types and power ratings."
  }
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""Nnnfinding book value of total assets

For example, if the asset value per share is higher than the market price for a share then the. Annaly capital management book value per share nly. How should a mutual fund investor interpret net asset value. Understand the difference between book value per common share and net asset value, and learn how these evaluations are used by investors and market analysts. Bvta book value of total assets finance acronymfinder. If the value of a plant asset suddenly falls so severely that its future cash flows are estimated to be less than its current book value, the asset is deemed to be impaired and an impairment loss is. How can we calculate market value of equity and book value of. Asset value does not take into account the share price. Asset turnover measures how quickly a company turns over its asset through sales. In short, when there are outstanding liabilities and have capital on one side of bala. Book value is a key measure that investors use to gauge a stocks valuation. Market value of equitybook value of total liabilities. The first equation deducts accumulated depreciation from the total assets to get the book value amount.

If you look up any balance sheet you will find that it is divided in 3 sections. If this was helpful please press the accept button. The book value of a company is the total value of the companys assets, minus the companys. The net property, plant, and equipment is the total book value of all of these assets. Overview book value per share is a well known measure for a company. Creating the net book value fixed asset report page 1 of 11 creating the net book value fixed asset report because of the way the data is kept, and that the system allows you. What is the difference between book value per common share. Investors often use the asset value of a company when determining if the companys shares are overvalued or undervalued. What is the book value of klingons total assets today. Altman explains that the ratio shows how much the firms assets can decline in value measured by market value of equity before the liabilities exceed the assets and the firm becomes. Net book value the difference between the depreciable basis and total depreciation is the remaining balance or nbv net book value a detailed depreciation can be run every month for the internal book schedule to get an accurate picture of the present value of your assets. One approach determines asset value by calculating what those assets are worth to their owners.

Traditionally, a companys book value is its total assets minus intangible. To define net book value, it can be rightly stated that it is the value at which the assets of a company are carried on its balance sheet. The book value calculation in practice is even simpler. To make this easier, convert total book value to book value per share. Because the return of owning an asset comes in the future, you use discounted. Book value of an asset is the value at which the asset is carried on a balance sheet and calculated by taking the cost of an asset minus the accumulated depreciation. The asset turnover ratio measures the ability of a company to use its. The net book value of a noncurrent asset is the net amount reported on the balance sheet for a longterm asset.

The price to book ratio or pb is calculated as market capitalization divided by its book value. Net book value is calculated as the original cost of an asset, minus any accumulated depreciation, accumulated depletion, accumulated amortization, and accumulated impairment. This is the price at which investors buy fund units from a fund company or sell it back to the fund house. Book value of total assets how is book value of total. Therefore, teslas asset turnover for the quarter that ended in dec. There are various equations for calculating book value. An initial investigation of firm size and debt use by. To illustrate net book value, lets assume that several years ago a company purchased equipment to be used in its business. The sum of current and longterm assets owned by a person, company, or other entity. Users are able to filter and tailor this report as desired for their specific use.

Total assets are the mix of working capital and non working capital fix assets and these both are essential. If they have no bv then they are not appearing on your balance sheet or the depreciation on. As history has shown many of us who live in canada, depreciating values for housing are not necessarily the most accurate representation for real estate. Book value is an assets original cost, less any accumulated depreciation and impairment charges that have been subsequently incurred. Book value can also be thought of as the net asset value of a company calculated as total assets minus intangible assets patents, goodwill.

The only way, whether there is a gain, loss, or none upon the sale, for the total assets to not change, is if the fixed assets in question had zero book value which means the fa was fully depreciated on the books. Fully depreciated asset still has remaining net book value. Asset value is an important component of a companys total value, and it can be computed in a number of ways. Stockopedia explains market value of equitybook value of total liabilities. In accounting, book value is the value of an asset according to its balance sheet account balance. Click the property book folder to display the total asset visibility report displayed on the right. Theoretically, book value represents the total amount a company is worth if all its assets are sold and all the liabilities are paid back. Ycharts book value of equity is the equivalent of total assets less total liabilities and preferred equity. It is simply the amount that the companys assets net of depreciation, depletion and amortization and total liabilities. The market value of debt, market versus book value of debt, and returns to assets richard j. The final amount of all gross investments, cash and equivalents, receivables, and other assets as they are presented on the balance sheet. The net book value can be defined in simple words as the net value of an asset. Traditionally, a companys book value is its total assets minus intangible assets and liabilities. The true market value of a property if it were offered for sale at a particular time to a buyer with sufficient information about the property to make an informed decision.

Fully depreciated asset still has remaining net book value nbv amount in fixed assets for microsoft dynamics gp. Fundamental analysts may use a companys asset value to determine whether it is. Book value of assets is defined as the value of an asset in the books of records of a company or institution or an individual at any given instance. This is calculated by dividing the net value of all the securities in the portfolio by the number of shares outstanding. It can be useful to compare the market price of shares to the book value. Consider a retailing firm with a net profit margin of 3. When impaired, the carrying value of goodwill is written down to fair value. The book value of a stock book value of total assets total liabilities. Book value also carrying value is an accounting term used to account for the effect of depreciation on an asset.

Nelcast total assets and asset turnover ratio financial graphs. Learn vocabulary, terms, and more with flashcards, games, and other study tools. Depreciation implies allocating the cost of a tangible fixed or longterm asset over its useful life. Accounting policy on goodwill and intangible assets goodwill is tested for impairment on an annual basis in the fourth fiscal quarter and, when specific circumstances dictate, between annual tests. It is calculated by dividing the total value of all the assets in a portfolio, minus all its liabilities. The difference between the market value mv and the book value bv. The value today is the discounted value of the sum of the dividend or service flow plus the future price of the asset. Contrast with book value, which is the original purchase price, plus capital expenditures, minus depreciation. The book value of an asset is the value of that asset on the books the accounting books and the balance sheet of the company. Net asset value nav represents a funds per unit market value. The market value of debt, market versus book value of debt. Book value of total assets how is book value of total assets abbreviated.

Market value is the worth of a company based on the total. The value of an asset is the most you would pay to own that asset. Sweeney is sullivandean professor of finance in the school of business at georgetown university. An initial investigation of firm size and debt use by small restaurant firms michael c. Lubar professor of finance at the university of wisconsinmilwaukee. The companys balance sheet is where youll find total asset value, and for accounting purposes, the cost of acquiring the asset is the starting. I am presuming that by total assets you are referring to the balance sheet presentation. For companies, it is calculated as the original cost of the asset less accumulated depreciation and impairment costs. Its important to note that the book value is not necessarily the same as the fair market value the amount the asset could be sold for on the open market. In the uk, book value is also known as net asset value. Book value refers to the value of an asset based on the current numbers in the balance sheet, or to the total value of a company according to its financial reports.

According to this measurement principle, the economic. Depreciation makes a part of the cost of asset chargeable as an expense in profit and loss account of the accounting periods in which the asset has helped in earning revenue. Net book value is the amount at which an organization records an asset in its accounting records. While small assets are simply held on the books at cost, larger assets like buildings and.

A loss recognized on an impaired asset equal to the difference between its book value and its current fair value. Can we make a conversion from book value to market value for. Total assets is the sum of all assets, current and fixed. Fixed asset depreciation detail report net book value report. The net market value of a companys assets divided by the number of outstanding shares of that companys stock. Your businesss net asset value is calculated by subtracting liabilities and intangible assets from total assets. Total assets per most recent financial statements 1450000. The asset turnover is calculated as total sales divided by ending total assets. It shows the current position of the asset base after liabilities are taken into account. Bvps is the net assets of a company after you deduct all of the liabilities. Assets definition of assets by the free dictionary.

The net asset value nav is the calculation that determines the value of a share in a fund of multiple securities, such as a mutual fund, hedge fund, or exchangetraded fund etf. In depth view into annaly capital management book value per share including historical data from 1997, charts, stats and industry comps. It is calculated as revenue divided by total assets. Book value involves the historical cost of assets held on the balance sheet and is primarily an accounting metric, which includes provisions such as depreciation. Book value is the total value of a business assets found on its balance sheet, and represents the value of all assets if liquidated. Book value is defined as total assets minus liabilities, preferred.

For assets, the value is based on the original cost of the asset less any depreciation, amortization or impairment costs made against the asset. Book value of assets definition, formula calculation. Why is it sometimes neccessary to writeoff fixed assets with no book value. Teslas total assets for the quarter that ended in dec. The book values of assets are routinely compared to market values as part of various financial analyses.

663 1458 752 1003 1558 100 43 426 671 1045 746 599 1587 355 1050 745 785 1152 344 1228 1532 303 920 104 25 1211 83 87 500 1059 930 10 115 834 132 34 783 202 272 1499 123 1411 530 1269"""

```json
{
  "format": {"score": 2, "justification": "The text is somewhat structured but has formatting issues, such as random numbers and lack of clear section headings. It is not completely unreadable, but it is not as polished as it could be."},
  "voice": {"score": 0, "justification": "The text lacks a distinctive authorial voice or style. It appears to be an informational piece with a generic tone rather than something with a unique perspective or voice."},
  "knowledge_density": {"score": 2, "justification": "The text contains a moderate amount of detailed information about book value, net asset value, and asset turnover. However, some sections are repetitive and contain filler content."},
  "diversity": {"score": 0, "justification": "The text mostly covers general accounting and finance topics without specialized or niche information. It does not demonstrate diversity in its content or approach."}
}
```


You are an expert evaluator. Rate the TEXT SAMPLE on four dimensions: Format, Voice, Knowledge Density, and Diversity.
Follow the rubrics exactly and return ONLY a JSON object that matches the schema below.

RUBRICS
1) Format (0–3)
  0 = Disorganized/unreadable
  1 = Partially structured; noticeable formatting issues
  2 = Mostly clear and well-structured; minor issues
  3 = Very clean, polished, professional formatting

2) Voice (0–1)
  0 = Generic tone; no distinct style
  1 = Clear, distinctive authorial voice/style

3) Knowledge Density (0–3)
  0 = Mostly filler/vague; little information
  1 = Some information but redundant/low substance
  2 = Moderately dense; clear informative content
  3 = Highly informative; most sentences add distinct info

4) Diversity (0–2)
  0 = Common/generic knowledge
  1 = Somewhat specialized/uncommon
  2 = Very niche/specialized/rare domain

OUTPUT SCHEMA (must be valid JSON; no extra text):
{
  "format":        {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "voice":         {"score": <int 0-1>, "justification": "<1–2 sentences>"},
  "knowledge_density": {"score": <int 0-3>, "justification": "<1–2 sentences>"},
  "diversity":     {"score": <int 0-2>, "justification": "<1–2 sentences>"}
}

CONSTRAINTS
- Use integers only for scores and keep them within the allowed ranges.
- Justifications must be concise (≤2 sentences each).
- Do not include any commentary outside the JSON object.

TEXT SAMPLE:
"""All News

5 ways to outfox foxes in Adelaide

Wednesday 06 October 2021

Foxes are a threat to many of Adelaide’s native animals, along with pet chickens, birds, guinea pigs and rabbits. Here’s four ways to reduce their threat.

Foxes are everywhere in metropolitan Adelaide. You can find foxes more-so around cities than rural areas for the simple reason that city life suits them. This is because there is plenty of food and shelter in urban areas.

Are foxes good or bad?

Foxes are an introduced and pest species in Australia.

Adelaide has a widespread population of them, and this is bad because they can:

  • hurt and kill Adelaide’s native animals
  • prey on pet rabbits, guinea pigs, chickens and other pet birds, and
  • carry a diseases like mange that can spread to pet dogs.

    As foxes have been around since the 1850s, most of our remaining native wildlife have adjusted to their presence, so eradicating foxes from our suburbs and cities is not realistic, we instead need to reduce their threat to native wildlife and our pets in metropolitan Adelaide.

    Here’s five ways you can reduce the threat of foxes across Adelaide:

    1. Keep your chicken coop secure

      Foxes are good climbers and can climb pens. So the best way to protect your chickens from raids is to fox-proof them in a fully enclosed pen or coop. A fox-proof enclosure should be made from material that foxes cannot jump over, chew through or dig under.

      2. Avoid leaving fox food lying around

        Foxes living a city life become scavengers and feed on anything – rubbish, food left out for pets, even fruit that’s fallen from backyard trees.

        3. Reduce fox access to potential shelter

          Foxes don’t need much living space and can build a den under a house, or a quiet part of a neighbourhood. Things like wood piles, old tires and green waste make great homes for foxes.

            4. Don’t feed wild native animals

              When you feed native animals this makes them less wary of others and this includes being less wary for foxes. So keep those snacks at home.

              5. Record sightings in FoxScan

              You can help control foxes in metropolitan Adelaide by recording sightings in FoxScan. Anyone can use FoxScan to record information about foxes. Information you record can be used to manage foxes more effectively to reduce the damage they cause. The more information you record, the more useful FoxScan will become for fox management.

              Fun fact: native animal tactics to outfox foxes

              Some native animals can outfox a fox, like possums and native water rats.

              Possums are known to race up tree tops and move around on rooves and power lines to keep safe. Whereas, native water rats (or rakali) keep safe by living in rivers and lakes and foxes prefer to stay dry.

                Ringtail possum. Picture: Martin Stokes

                Remember, though some may look cute, it’s illegal to keep foxes as pets in South Australia.

                  This story was originally published in May 2021.

                  Like what you’ve read? Browse Green Adelaide’s other nature stories, subscribe to our monthly newsletter or follow us on Facebook and Instagram."""

```json
{
  "format": {"score": 2, "justification": "The text is well-structured with clear headings and subheadings. However, there are minor formatting inconsistencies, such as inconsistent bullet points and some paragraphs that could be more concise."},
  "voice": {"score": 1, "justification": "The text has a clear, informative voice, but it is not particularly distinctive or unique. It provides practical advice but lacks a strong personal or authorial style."},
  "knowledge_density": {"score": 2, "justification": "The text provides specific, actionable information on reducing fox threats in Adelaide, with details on various methods and their implications. However, some sections could be more detailed."},
  "diversity": {"score": 1, "justification": "The content is somewhat specialized, focusing on foxes in Adelaide, but it does not delve into highly niche or rare topics."}
}
```