diff --git a/.gitignore b/.gitignore index 9b5695c52..c9ee75a04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -out -workspace.xml \ No newline at end of file +out/ +build/ +workspace.xml diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..f12c48c7c --- /dev/null +++ b/build.gradle @@ -0,0 +1,36 @@ +group 'org.kotlinlang' +version '1.0-SNAPSHOT' + +buildscript { + // So we can use $kotlin_version in specifying dependencies. + ext.kotlin_version = '1.0.0' + + repositories { + mavenCentral() + } + + dependencies { + // Kotlin support for Gradle + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: 'kotlin' +apply plugin: 'java' + +repositories { + mavenCentral() +} + +dependencies { + // Kotlin library and reflection stuff + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + + // Kotlin testing + testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" +} + +// For ease of startup +task wrapper(type: Wrapper) { + gradleVersion = '2.11' +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..5ccda13e9 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..41fc0edbd --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Feb 19 11:56:26 CST 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-bin.zip diff --git a/gradlew b/gradlew new file mode 100755 index 000000000..9d82f7891 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..5f192121e --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/kotlin-koans.iml b/kotlin-koans.iml index 772215cd1..3539cc0a7 100644 --- a/kotlin-koans.iml +++ b/kotlin-koans.iml @@ -3,8 +3,9 @@ + - + @@ -28,5 +29,4 @@ - - + \ No newline at end of file diff --git a/src/i_introduction/_0_Hello_World/HelloWorld.kt b/src/i_introduction/_0_Hello_World/HelloWorld.kt index 70138b52a..595adfbcc 100644 --- a/src/i_introduction/_0_Hello_World/HelloWorld.kt +++ b/src/i_introduction/_0_Hello_World/HelloWorld.kt @@ -3,14 +3,40 @@ package i_introduction._0_Hello_World import util.TODO import util.doc0 +/** + * Description of task. + */ fun todoTask0(): Nothing = TODO( - """ - Introduction: + """ + Task 0 - Workshop tasks are usually to change the function 'taskN' by replacing its body - (which starts out as the function invocation 'todoTaskN()'), with the correct code according to the problem. - The function 'todoTaskN()' throws an exception, so you usually have to replace that invocation with - meaningful code. + Introduction + + The Kotlin Koans Workshop aims to teach you Kotlin by writing code + to solve tasks. For each task, there is an associated unit test that + checks your solution. You can run all of the tests (check all of the work + so far) by executing the "All tests" target. + + Individual workshop tasks (this one, task0, is the first of many) generally + require you to change the function 'taskN' by completely replacing the body + of the function in order to solve the problem and allow the associated unit + test to pass. If you run the unit test for a task that is not correct, the + unit test results will be displayed. If you have not yet made any changes + to a task, the task's TODO message will be displayed and exception will be + thrown. This message will provide guidance on the task to be performed. + + In this example (this file), this means replacing the code below + + fun task0(): String { + return todoTask0() + } + + with the correct, meaningful code in order to solve the problem and allow the associated + unit test to pass, such as: + + fun task0(): String { + return "OK" + } Using 'documentation' argument you can open the related part of Kotlin online documentation. Press 'F1' (Quick Documentation) on 'doc0()', "See also" section gives you a link. @@ -18,11 +44,16 @@ fun todoTask0(): Nothing = TODO( Using 'references' you can usually navigate and see the code mentioned in the task description. To start please make the function 'task0' return "OK". - """, - documentation = doc0(), - references = { task0(); "OK" } + """, + documentation = doc0(), + references = { task0(); "OK" } ) +/** + * Replace the function body of this method as described in todoTask0(). + * + * @return the string literal "OK". + */ fun task0(): String { return todoTask0() } diff --git a/src/i_introduction/_10_Object_Expressions/ObjectExpressions.kt b/src/i_introduction/_10_Object_Expressions/ObjectExpressions.kt index 88b138aec..7e8bee001 100644 --- a/src/i_introduction/_10_Object_Expressions/ObjectExpressions.kt +++ b/src/i_introduction/_10_Object_Expressions/ObjectExpressions.kt @@ -4,18 +4,33 @@ import util.TODO import util.doc10 import java.util.* +/** + * Description of task. + */ fun todoTask10(): Nothing = TODO( - """ - Task 10. - Read about object expressions that play the same role in Kotlin as anonymous classes do in Java. + """ + Task 10 - Add an object expression that provides a comparator to sort a list in a descending order using java.util.Collections class. - In Kotlin you use Kotlin library extensions instead of java.util.Collections, - but this example is still a good demonstration of mixing Kotlin and Java code. - """, - documentation = doc10() + Object expressions that play the same role in Kotlin as anonymous classes do in Java. + + The goal of this task is to sort the List of Int using an object expression that + provides a comparator to sort a list of Int in a descending order using java.util.Collections + class. + + In Kotlin you use Kotlin library extensions instead of java.util.Collections, but this example + is still a good demonstration of mixing Kotlin and Java code. + """, + documentation = doc10() ) +/** + * MODIFY the function body of this method as described in todoTask10(). + * The ideal solution to this will be to replace the text of "todoTask10()" in the function body + * with an inline object expression that creates a "Comparator of Int" object that overrides the + * compare(l: Int, r: Int) function to provide a descending sort. + * + * @return a List of Int where the list is a pre-specified list of Int's sorted in descending order. + */ fun task10(): List { val arrayList = arrayListOf(1, 5, 2) Collections.sort(arrayList, todoTask10()) diff --git a/src/i_introduction/_11_SAM_Conversions/SAMConversions.kt b/src/i_introduction/_11_SAM_Conversions/SAMConversions.kt index 03cff9ccf..3bb405df3 100644 --- a/src/i_introduction/_11_SAM_Conversions/SAMConversions.kt +++ b/src/i_introduction/_11_SAM_Conversions/SAMConversions.kt @@ -4,19 +4,47 @@ import util.TODO import util.doc11 import java.util.* +/** + * Description of task. + */ fun todoTask11(): Nothing = TODO( - """ - Task 11. - When an object implements a SAM interface (one with a Single Abstract Method), you can pass a lambda instead. + """ + Task 11 + + A Java class is considered to implement the SAM (Single Abstract Method) interface when it provides + a single worker method (you can ignore methods like toString(), equals(), hashCode()). Looking + at Java's Collection interface + + https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html + + We see that Comparator (ignoring the equals() method) only requires implementation + a of single methodL: compare(T, T). Although compare(T, T) isn't Abstract (for that + matter Comparator is an Interface, not an abstract class), none the less, Comparator + is still consdered to be a SAM. + + When the parameter to a function is of a type that implements the SAM pattern, + you can replace that parameter with a simple lamba that contains the correct number + of arguments. + Read more about SAM conversions in the blog posts about Kotlin. - Rewrite the previous example changing an object expression to a lambda. - """, - documentation = doc11() + The goal of this task is to rewrite the previous example changing an object expression + to a single lambda. The bulk of the code is already in place, just replace, within + task11(), the text "todoTask11()" with the appropriate expression or logic. + """, + documentation = doc11() ) +/** + * MODIFY the function body of this method as described in todoTask11(). + * The ideal solution to this will be to replace the text of "todoTask11()" in the function body + * with an expression like that found in the body of the comparator(x Int: y:Int) { } function + * you wrote in task10. + * + * @return a List of Int where the list is a pre-specified list of Int's sorted in descending order. + */ fun task11(): List { val arrayList = arrayListOf(1, 5, 2) - Collections.sort(arrayList, { x, y -> todoTask11() }) + Collections.sort(arrayList, { l, r -> todoTask11() }) return arrayList } diff --git a/src/i_introduction/_12_Extensions_On_Collections/ExtensionsOnCollections.kt b/src/i_introduction/_12_Extensions_On_Collections/ExtensionsOnCollections.kt index 7bd11d3d9..b422ab3b0 100644 --- a/src/i_introduction/_12_Extensions_On_Collections/ExtensionsOnCollections.kt +++ b/src/i_introduction/_12_Extensions_On_Collections/ExtensionsOnCollections.kt @@ -3,19 +3,36 @@ package i_introduction._12_Extensions_On_Collections import util.TODO import util.doc12 +/** + * Description of task. + */ fun todoTask12(): Nothing = TODO( - """ - Task 12. - In Kotlin standard library there are lots of extension functions that make the work with collections more convenient. - Rewrite the previous example once more using an extension function 'sortedDescending'. + """ + Task 12 + + The Kotlin standard library includes many extension functions, making the Java standard library + easier to use and more convenient. + + One of the additions Kotlin makes to the Java standard library is adding the sortedDescending() + to Java's Collection object. + + Rewrite the previous example once more using Kotin's Collection extension function 'sortedDescending()'. + + Because Kotlin can extend existing Java classes, it wasn't necessary for Kotin to introduce their + own Collection-related classes. Kotlin mere using the existing Java classes but improves them. - Kotlin code can be easily mixed with Java code. - Thus in Kotlin we don't introduce our own collections, but use standard Java ones (slightly improved). Read about read-only and mutable views on Java collections. - """, - documentation = doc12() + """, + documentation = doc12() ) +/** + * MODIFY the function body of this method as described in todoTask11(). + * The ideal solution to this will be to replace the text of "todoTask11()" in the function body + * with an expression must like the body of the comparator(x Int: y:Int) function you write in task10. + * + * @return a List of Int where the list is a pre-specified list of Int's sorted in descending order. + */ fun task12(): List { todoTask12() return arrayListOf(1, 5, 2) diff --git a/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaCode1.java b/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaCode1.java index f373204aa..314cd8f3d 100644 --- a/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaCode1.java +++ b/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaCode1.java @@ -5,6 +5,10 @@ import java.util.Collection; import java.util.Iterator; +/** + * Example class for task 1. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode1 extends JavaCode { public String task1(Collection collection) { StringBuilder sb = new StringBuilder(); diff --git a/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaToKotlinConverter.kt b/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaToKotlinConverter.kt index b5a750492..8c297f68a 100644 --- a/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaToKotlinConverter.kt +++ b/src/i_introduction/_1_Java_To_Kotlin_Converter/JavaToKotlinConverter.kt @@ -2,16 +2,33 @@ package i_introduction._1_Java_To_Kotlin_Converter import util.TODO +/** + * Description of task. + */ fun todoTask1(collection: Collection): Nothing = TODO( - """ - Task 1. - Rewrite JavaCode1.task1 in Kotlin. - In IntelliJ IDEA, you can just copy-paste the code and agree to automatically convert it to Kotlin, - but only for this task! - """, - references = { JavaCode1().task1(collection) }) + """ + Task 1 + The logic for this task exists in java class JavaCode1, which is in this same folder. + The goal of this task is to replace the body of task1(collection) with the logic + found in JavaCode1.task1(collection), but you need to re-write the logic in Kotlin. + Note: If you copy the JavaCode1.task1(collection) logic and paste it into this + file's task1(collection) function, IntelliJ will offer to automatically convert + the code from Java to Kotlin for you. Give the automatic conversion a try! + In the future, you will want to reject the automatic conversion and manually + translate the code from Java to Kotlin so you don't cheat yourself out of + the learning opportunity. + """, + references = { JavaCode1().task1(collection) }) + + +/** + * Modify the function body of this method as described in todoTask1(). + * + * @param collection a collection of Int + * @return If the incoming collection is [1, 12, 3] the output should be "{1, 12, 3}". + */ fun task1(collection: Collection): String { todoTask1(collection) } diff --git a/src/i_introduction/_2_Named_Arguments/NamedArguments.kt b/src/i_introduction/_2_Named_Arguments/NamedArguments.kt index 2729d42ef..a757ca59b 100644 --- a/src/i_introduction/_2_Named_Arguments/NamedArguments.kt +++ b/src/i_introduction/_2_Named_Arguments/NamedArguments.kt @@ -12,16 +12,32 @@ fun usage() { bar(1, b = false) } +/** + * Description of task. + */ fun todoTask2(): Nothing = TODO( - """ - Task 2. - Implement the same logic as in 'task1' again through the library method 'joinToString()'. - Specify only two of the 'joinToString' arguments. - """, - documentation = doc2(), - references = { collection: Collection -> task1(collection); collection.joinToString() }) + """ + Task 2 + The logic defined in 'task1' is re-inventing the wheel. The Kotlin standard library + contains a method named 'joinToString() that can provide the exact same functionality, + if you provide the correct arguments. + + Replace the body of the function task2(collection) with code that will + return the result of collection.joinToString() with appropriate arguments + as to provide the same result as task1's JavaCode1.task1(collection). + Your solution should pass only two arguments to joinToString(). + """, + documentation = doc2(), + references = { collection: Collection -> task1(collection); collection.joinToString() }) + +/** + * Modify the function body of this method as described in todoTask2(). + * + * @param collection a collection of Int + * @return If the incoming collection is [1, 12, 3] the output should be "{1, 12, 3}". + */ fun task2(collection: Collection): String { todoTask2() - return collection.joinToString() + //return collection.joinToString(/*some arguments*/) } diff --git a/src/i_introduction/_3_Default_Arguments/DefaultAndNamedParams.kt b/src/i_introduction/_3_Default_Arguments/DefaultAndNamedParams.kt index 11b9e179a..5134b6ec7 100644 --- a/src/i_introduction/_3_Default_Arguments/DefaultAndNamedParams.kt +++ b/src/i_introduction/_3_Default_Arguments/DefaultAndNamedParams.kt @@ -3,23 +3,44 @@ package i_introduction._3_Default_Arguments import util.TODO import util.doc2 +/** + * Description of task. + */ fun todoTask3(): Nothing = TODO( - """ - Task 3. + """ + Task 3 + Several overloads of 'JavaCode3.foo()' can be replaced with one function in Kotlin. - Change the declaration of the function 'foo' in a way that makes the code using 'foo' compile. - You have to add parameters and replace 'todoTask3()' with a real body. - Uncomment the commented code and make it compile. - """, - documentation = doc2(), - references = { name: String -> JavaCode3().foo(name); foo(name) }) -fun foo(name: String): String = todoTask3() + The task3() function contents must be modified to remove the line "return todoTask3()" + and un-comment the four lines starting with "return (foo("A") +". + + The goal of this task is to change the list of arguments for the function 'foo', provided + just below, and replace the function implementation such that the code in task3() will return + the String "a42b1C42D2". + """, + documentation = doc2(), + references = { name: String -> JavaCode3().foo(name); foo(name) }) + +/** + * Function to create string that contains a specified string, possibly as upper case (default is lowercase), + * followed by a specified (or default) number. If the number is not provided, the default number should be 42. + * + * Optionally, complete the KDoc, here. + * @return a string of (string, possibly upper case) with a number concatenated to it + */ +fun foo(name: String /* more arguments will go here*/): String = todoTask3() +/** + * Modify the function body of this method as described in todoTask3(). + * + * @return the literal string "a42b1C42D2" as computed by this function with multiple + * calls to the foo(...) function. + */ fun task3(): String { - todoTask3() -// return (foo("a") + -// foo("b", number = 1) + -// foo("c", toUpperCase = true) + -// foo(name = "d", number = 2, toUpperCase = true)) + return todoTask3() + //return (foo("a") + + // foo("b", number = 1) + + // foo("c", toUpperCase = true) + + // foo(name = "d", number = 2, toUpperCase = true)) } diff --git a/src/i_introduction/_3_Default_Arguments/JavaCode3.java b/src/i_introduction/_3_Default_Arguments/JavaCode3.java index 40ecb16e2..8897f9246 100644 --- a/src/i_introduction/_3_Default_Arguments/JavaCode3.java +++ b/src/i_introduction/_3_Default_Arguments/JavaCode3.java @@ -2,6 +2,10 @@ import util.JavaCode; +/** + * Example class for task 3. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode3 extends JavaCode { private int defaultNumber = 42; diff --git a/src/i_introduction/_4_Lambdas/JavaCode4.java b/src/i_introduction/_4_Lambdas/JavaCode4.java index 7938be547..7b522ce26 100644 --- a/src/i_introduction/_4_Lambdas/JavaCode4.java +++ b/src/i_introduction/_4_Lambdas/JavaCode4.java @@ -6,6 +6,10 @@ import java.util.Collection; +/** + * Example class for task 4. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode4 extends JavaCode { public boolean task4(Collection collection) { return Iterables.any(collection, new Predicate() { diff --git a/src/i_introduction/_4_Lambdas/Lambdas.kt b/src/i_introduction/_4_Lambdas/Lambdas.kt index e2685400f..800ad8a73 100644 --- a/src/i_introduction/_4_Lambdas/Lambdas.kt +++ b/src/i_introduction/_4_Lambdas/Lambdas.kt @@ -4,23 +4,35 @@ import util.TODO import util.doc4 fun example() { - val sum = { x: Int, y: Int -> x + y } val square: (Int) -> Int = { x -> x * x } sum(1, square(2)) == 5 } +/** + * Description of task. + */ fun todoTask4(collection: Collection): Nothing = TODO( - """ - Task 4. - Rewrite 'JavaCode4.task4()' in Kotlin using lambdas. - You can find the appropriate function to call on 'collection' through IntelliJ IDEA's code completion feature. - (Don't use the class 'Iterables'). - """, - documentation = doc4(), - references = { JavaCode4().task4(collection) }) - + """ + Task 4 + + Replace the implementation of task4(collection) to provide the same logic as + found in JavaCode4.task4(collection). Your Kotlin solution should use + lambdas. + + You can find the appropriate function to call on 'collection' through + IntelliJ's code completion feature. (Don't use the class 'Iterables'). + """, + documentation = doc4(), + references = { JavaCode4().task4(collection) }) + +/** + * Replace the function body of this method as described in todoTask4(). + * + * @param input a collection of Int's + * @return true of any of the elements of collection are divisible by 42 + */ fun task4(collection: Collection): Boolean = todoTask4(collection) diff --git a/src/i_introduction/_5_String_Templates/StringTemplates.kt b/src/i_introduction/_5_String_Templates/StringTemplates.kt index 13cd01234..d1d67f09a 100644 --- a/src/i_introduction/_5_String_Templates/StringTemplates.kt +++ b/src/i_introduction/_5_String_Templates/StringTemplates.kt @@ -3,14 +3,26 @@ package i_introduction._5_String_Templates import util.TODO import util.doc5 +/** + * Example function that demonstrates simple string interpolation. + */ fun example1(a: Any, b: Any) = "This is some text in which variables ($a, $b) appear." +/** + * Example function using normal Java string concatenation (not using interpolation). + */ fun example2(a: Any, b: Any) = "You can write it in a Java way as well. Like this: " + a + ", " + b + "!" +/** + * Example function demonstrates a string interpolation where the interpolation is a expression. + */ fun example3(c: Boolean, x: Int, y: Int) = "Any expression can be used: ${if (c) x else y}" +/** + * Example function using raw strings covering multiple lines with embedded string interpolation. + */ fun example4() = """ You can use raw strings to write multiline text. @@ -19,20 +31,45 @@ you don't need to escape a backslash by a backslash. String template entries (${42}) are allowed here. """ +/** + * Example function showing raw strings to create a regular expression string. + */ fun getPattern() = """\d{2}\.\d{2}\.\d{4}""" +/** + * Example function demonstrating the ability to use the getPattern() matcher to + * match a date in the getPattern() format. + */ fun example() = "13.06.1992".matches(getPattern().toRegex()) //true -val month = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)" - +/** + * Description of task. + */ fun todoTask5(): Nothing = TODO( - """ - Task 5. - Copy the body of 'getPattern()' to the 'task5()' function - and rewrite it in such a way that it matches '13 JUN 1992'. - Use the 'month' variable. - """, - documentation = doc5(), - references = { getPattern(); month }) + """ + Task 5 + + The goal of this task is to replace the task5() function implementation + to return a regular expression string that can be used to match dates + formatted such as '13 JUN 1992' (excluding the quotes). + + The getPattern() function (above) is an example regular expression string + that nearly solves this task, but not quite. + + The solution of your task should use the provided 'month' variable (above). + """, + documentation = doc5(), + references = { getPattern(); month }) + +/** + * A regular expression string is capable of matching the months in 3 letter uppercase. + * Use this variable in your task solution. + */ +val month = "(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)" +/** + * Replace the function body of this method as described in todoTask5(). + * + * @return A regular expression string to match dates formatted such as '13 JUN 1992' + */ fun task5(): String = todoTask5() diff --git a/src/i_introduction/_6_Data_Classes/DataClasses.kt b/src/i_introduction/_6_Data_Classes/DataClasses.kt index 474490bc8..04cc3b970 100644 --- a/src/i_introduction/_6_Data_Classes/DataClasses.kt +++ b/src/i_introduction/_6_Data_Classes/DataClasses.kt @@ -3,21 +3,41 @@ package i_introduction._6_Data_Classes import util.TODO import util.doc6 +/** + * Description of task. + */ fun todoTask6(): Nothing = TODO( - """ - Convert 'JavaCode6.Person' class to Kotlin. - Then add a modifier `data` to the resulting class. - This annotation means the compiler will generate a bunch of useful methods in this class: `equals`/`hashCode`, `toString` and some others. - The `task6` function should return a list of persons. - """, - documentation = doc6(), - references = { JavaCode6.Person("Alice", 29) } + """ + Task 6 + + The goal of this class is to learn out to simplify the Person class found in JavaCode6 + by writing it in Kotlin and placing the new simplified Person class here in this file by + completing the definition of "class Person" found just below. + + To-do: + * Complete the Person class (just below), your definition should fit on a single line + * Make the class a "data" class to automatically have the compiler generate a bunch of + useful methods in this class: `equals`/`hashCode`, `toString` and some others. + * Modify the task6() function should return a list of Person. Uncomment the //return line + and remove the todoTask6() line. + """, + documentation = doc6(), + references = { JavaCode6.Person("Alice", 29) } ) +/** + * The class to create as described in todoTask6() + */ class Person +/** + * Modify the function body of this method as described in todoTask6(). + * The //return line within task6() + * + * @return a list of two Person objects, one for Alice and one for Bob. + */ fun task6(): List { todoTask6() - return listOf(/*Person("Alice", 29), Person("Bob", 31)*/) + //return listOf(/*Person("Alice", 29), Person("Bob", 31)*/) } diff --git a/src/i_introduction/_6_Data_Classes/JavaCode6.java b/src/i_introduction/_6_Data_Classes/JavaCode6.java index 7d18a0f7a..a03ad0344 100644 --- a/src/i_introduction/_6_Data_Classes/JavaCode6.java +++ b/src/i_introduction/_6_Data_Classes/JavaCode6.java @@ -2,6 +2,10 @@ import util.JavaCode; +/** + * Example class for task 6. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode6 extends JavaCode { public static class Person { diff --git a/src/i_introduction/_7_Nullable_Types/JavaCode7.java b/src/i_introduction/_7_Nullable_Types/JavaCode7.java index df176b6e6..827fc0469 100644 --- a/src/i_introduction/_7_Nullable_Types/JavaCode7.java +++ b/src/i_introduction/_7_Nullable_Types/JavaCode7.java @@ -4,6 +4,10 @@ import org.jetbrains.annotations.Nullable; import util.JavaCode; +/** + * Example class for task 7. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode7 extends JavaCode { public void sendMessageToClient(@Nullable Client client, @Nullable String message, @NotNull Mailer mailer) { if (client == null || message == null) return; diff --git a/src/i_introduction/_7_Nullable_Types/NullableTypes.kt b/src/i_introduction/_7_Nullable_Types/NullableTypes.kt index 2bb3171b7..4dd423720 100644 --- a/src/i_introduction/_7_Nullable_Types/NullableTypes.kt +++ b/src/i_introduction/_7_Nullable_Types/NullableTypes.kt @@ -12,21 +12,32 @@ fun test() { val j: Int = q?.length ?: 0 // 0 } +/** + * Description of task. + */ fun todoTask7(client: Client?, message: String?, mailer: Mailer): Nothing = TODO( - """ - Task 7. - Rewrite JavaCode7.sendMessageToClient in Kotlin, using only one 'if' expression. - Declarations of Client, PersonalInfo and Mailer are given below. - """, - documentation = doc7(), - references = { JavaCode7().sendMessageToClient(client, message, mailer) } -) + """ + Task 7 -fun sendMessageToClient( - client: Client?, message: String?, mailer: Mailer -) { - todoTask7(client, message, mailer) -} + The goal of this task is to introduce you to Nullable Types, which Kotin decorates + with the "?" symbol to the right of (but connected to) the type. For example + the type "Int" must contain a valid Int value (such as 15), but the type + "Int?" may contain a normal Int value OR it might be null + + When a val (value) or var (variable) is of a nullable type, before obtaining the + value of that value or variable, Kotlin forces you to verify that the value is not null. + + Replace the body of the below function sendMessageToClient(...) such that + it uses the same logic found in JavaCode7.sendMessageToClient(...). + Use only one 'if' expression. Declarations of Client, PersonalInfo and Mailer are given below. + + Make sure you look at the test() function above and understand the functioning of the + various operators used. Of special interest is the "?:" operator, which is commonly + referred to as the "Elvis Operator". + """, + documentation = doc7(), + references = { JavaCode7().sendMessageToClient(client, message, mailer) } +) class Client (val personalInfo: PersonalInfo?) class PersonalInfo (val email: String?) @@ -34,3 +45,12 @@ class PersonalInfo (val email: String?) interface Mailer { fun sendMessage(email: String, message: String) } + +/** + * Replace the function body of this method as described in todoTask7(). + * + * @return + */ +fun sendMessageToClient(client: Client?, message: String?, mailer: Mailer) { + todoTask7(client, message, mailer) +} diff --git a/src/i_introduction/_8_Smart_Casts/JavaCode8.java b/src/i_introduction/_8_Smart_Casts/JavaCode8.java index 4a40edc0c..8a9548270 100644 --- a/src/i_introduction/_8_Smart_Casts/JavaCode8.java +++ b/src/i_introduction/_8_Smart_Casts/JavaCode8.java @@ -2,6 +2,10 @@ import util.JavaCode; +/** + * Example class for task 8. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode8 extends JavaCode { public int eval(Expr expr) { if (expr instanceof Num) { diff --git a/src/i_introduction/_8_Smart_Casts/SmartCasts.kt b/src/i_introduction/_8_Smart_Casts/SmartCasts.kt index d61eccc2c..05b3c35d6 100644 --- a/src/i_introduction/_8_Smart_Casts/SmartCasts.kt +++ b/src/i_introduction/_8_Smart_Casts/SmartCasts.kt @@ -3,10 +3,45 @@ package i_introduction._8_Smart_Casts import util.TODO import util.doc8 +/** + * Description of task. + */ +fun todoTask8(expr: Expr): Nothing = TODO( + """ + Task 8 + + The goal of this task is to replace both instances of the code "todoTask8(e)" + within the below function eval(e: Eval) with the appropriate code to perform + the same logic as found in JavCode8.eval(Expr expr). + + As show in the partial solution below in the eval(e: Eval) function, your + solution should use the Kotin "when" control structure. Additionally, make sure + to include an "else" clause. + """, + documentation = doc8(), + references = { JavaCode8().eval(expr) }) + +/** + * An interface for defining pieces of an expression. + */ interface Expr + +/** + * A number literal expression. + */ class Num(val value: Int) : Expr + +/** + * A sum expression, which represents the sum of the two specified Expr expression elements. + */ class Sum(val left: Expr, val right: Expr) : Expr +/** + * MODIFY the function body of this method as described in todoTask8(). + * + * @param e a Expr object (such as a Num or Sum object) + * @return the solution to the expression e + */ fun eval(e: Expr): Int = when (e) { is Num -> todoTask8(e) @@ -14,11 +49,4 @@ fun eval(e: Expr): Int = else -> throw IllegalArgumentException("Unknown expression") } -fun todoTask8(expr: Expr): Nothing = TODO( - """ - Task 8. - Rewrite 'JavaCode8.eval()' in Kotlin using smart casts and 'when' expression. - """, - documentation = doc8(), - references = { JavaCode8().eval(expr) }) diff --git a/src/i_introduction/_9_Extension_Functions/ExtensionFunctions.kt b/src/i_introduction/_9_Extension_Functions/ExtensionFunctions.kt index 056170fb8..1b365c1fc 100644 --- a/src/i_introduction/_9_Extension_Functions/ExtensionFunctions.kt +++ b/src/i_introduction/_9_Extension_Functions/ExtensionFunctions.kt @@ -3,6 +3,7 @@ package i_introduction._9_Extension_Functions import util.TODO import util.doc9 +// 'lastChar' is compiled to a static function in the class ExtensionFunctionsKt (see JavaCode9.useExtension) fun String.lastChar() = this.get(this.length - 1) // 'this' can be omitted @@ -13,21 +14,43 @@ fun use() { "abc".lastChar() } -// 'lastChar' is compiled to a static function in the class ExtensionFunctionsKt (see JavaCode9.useExtension) - +/** + * Description of task. + */ fun todoTask9(): Nothing = TODO( - """ - Task 9. - Implement the extension functions Int.r(), Pair.r() - to support the following manner of creating rational numbers: - 1.r(), Pair(1, 2).r() - """, - documentation = doc9(), - references = { 1.r(); Pair(1, 2).r(); RationalNumber(1, 9) }) - + """ + Task 9 + + The goal of this task is to implement the extension functions Int.r(), Pair.r() + to support the following manner of creating rational numbers: 1.r(), Pair(1, 2).r(). + If a denominator is not provided (as in the case of Int.r()), use a denominator of 1. + """, + documentation = doc9(), + references = { 1.r(); Pair(1, 2).r(); RationalNumber(1, 9) }) + +/** + * A class defining a RationalNumber. Given that this class is a "data" class, + * .toString(), .equals(), and .hashcode() will be created automatically for this class. + */ data class RationalNumber(val numerator: Int, val denominator: Int) +/** + * Replace the function body of this method as described in todoTask9(). + * + * Extend the class Int to add a function r() which returns a RationalNumber + * with the numerator having the Int's value and a denominator being 1. + * + * @return the solution to the expression e + */ fun Int.r(): RationalNumber = todoTask9() -fun Pair.r(): RationalNumber = todoTask9() - +/** + * Replace the function body of this method as described in todoTask9(). + * + * Extend the class Pair of Int, int to add a function r() which returns a RationalNumber + * setting the numerator to the Pair's .first value and setting the denominator + * to the Pair's .second value. + * + * @return the solution to the expression e + */ +fun Pair.r(): RationalNumber = todoTask9() diff --git a/src/i_introduction/_9_Extension_Functions/JavaCode9.java b/src/i_introduction/_9_Extension_Functions/JavaCode9.java index 764be041e..62af7d5f9 100644 --- a/src/i_introduction/_9_Extension_Functions/JavaCode9.java +++ b/src/i_introduction/_9_Extension_Functions/JavaCode9.java @@ -2,6 +2,10 @@ import util.JavaCode; +/** + * Example class for task 9. + * DO NOT CHANGE THIS FILE. + */ public class JavaCode9 extends JavaCode { public void useExtension() { char c = ExtensionFunctionsKt.lastChar("abc"); diff --git a/src/ii_collections/_24_JavaCode.java b/src/ii_collections/JavaCode24.java similarity index 90% rename from src/ii_collections/_24_JavaCode.java rename to src/ii_collections/JavaCode24.java index 0dc0e703e..4d187171c 100644 --- a/src/ii_collections/_24_JavaCode.java +++ b/src/ii_collections/JavaCode24.java @@ -8,7 +8,11 @@ import java.util.List; import java.util.Map; -public class _24_JavaCode extends JavaCode { +/** + * Example class for task 24. + * DO NOT CHANGE THIS FILE. + */ +public class JavaCode24 extends JavaCode { public Collection doSomethingStrangeWithCollection(Collection collection) { Map> groupsByLength = Maps.newHashMap(); for (String s : collection) { diff --git a/src/ii_collections/_13_Introduction_.kt b/src/ii_collections/_13_Introduction_.kt index 651a84e3a..5162f8ecb 100644 --- a/src/ii_collections/_13_Introduction_.kt +++ b/src/ii_collections/_13_Introduction_.kt @@ -3,12 +3,12 @@ package ii_collections import java.util.* /* - * This part of workshop was inspired by: + * This task was inspired by: * https://github.com/goldmansachs/gs-collections-kata */ -/* - * There are many operations that help to transform one collection into another, starting with 'to' +/** + * Example function demonstrating conversion of a list to a set. */ fun example0(list: List) { list.toSet() @@ -17,9 +17,33 @@ fun example0(list: List) { list.to(set) } +/** + * Description of task. + */ +fun todoTask13(): Nothing = util.TODO( + """ + Task 13 + + In Kotlin, there are many operations that help to transform one collection into another, starting with 'to'. + + The goal of this exercise is to replace the entire body (blow) of function Shop.getSetOfCustomers() + to return a set of all customers of Shop. + + This function, Shop.getSetOfCustomers(), adds a new function getSetOfCustomers() to the existing Shop class. + You can find the Shop.kt class in the same folder as this exercise (and all of the other + section ii_collections exercises). + """, + references = { shop: Shop -> shop.customers } +) + +/** + * Augment the Shop class, obtaining the set of customers. + * + * @return a set (not a list) containing all the customers of this shop + */ fun Shop.getSetOfCustomers(): Set { - // Return a set containing all the customers of this shop - todoCollectionTask() -// return this.customers + // + todoTask13() + //return this.customers } diff --git a/src/ii_collections/_14_FilterMap.kt b/src/ii_collections/_14_FilterMap.kt index c547b44b6..ddb032b49 100644 --- a/src/ii_collections/_14_FilterMap.kt +++ b/src/ii_collections/_14_FilterMap.kt @@ -1,21 +1,32 @@ package ii_collections fun example1(list: List) { - // If a lambda has exactly one parameter, that parameter can be accessed as 'it' val positiveNumbers = list.filter { it > 0 } val squares = list.map { it * it } } +/** + * Description of task. + */ +fun todoTask14(): Nothing = util.TODO( + """ + Task 14 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getCitiesCustomersAreFrom(): Set { // Return the set of cities the customers are from - todoCollectionTask() + todoTask14() } fun Shop.getCustomersFrom(city: City): List { // Return a list of the customers who live in the given city - todoCollectionTask() + todoTask14() } - - diff --git a/src/ii_collections/_15_AllAnyAndOtherPredicates.kt b/src/ii_collections/_15_AllAnyAndOtherPredicates.kt index 788d64bfa..225d394d7 100644 --- a/src/ii_collections/_15_AllAnyAndOtherPredicates.kt +++ b/src/ii_collections/_15_AllAnyAndOtherPredicates.kt @@ -1,39 +1,49 @@ package ii_collections fun example2(list: List) { - val isZero: (Int) -> Boolean = { it == 0 } - val hasZero: Boolean = list.any(isZero) - val allZeros: Boolean = list.all(isZero) - val numberOfZeros: Int = list.count(isZero) - val firstPositiveNumber: Int? = list.firstOrNull { it > 0 } } +/** + * Description of task. + */ +fun todoTask15(): Nothing = util.TODO( + """ + Task 15 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + + """, + references = { shop: Shop -> shop.customers } +) + fun Customer.isFrom(city: City): Boolean { // Return true if the customer is from the given city - todoCollectionTask() + todoTask15() } fun Shop.checkAllCustomersAreFrom(city: City): Boolean { // Return true if all customers are from the given city - todoCollectionTask() + todoTask15() } fun Shop.hasCustomerFrom(city: City): Boolean { // Return true if there is at least one customer from the given city - todoCollectionTask() + todoTask15() } fun Shop.countCustomersFrom(city: City): Int { // Return the number of customers from the given city - todoCollectionTask() + todoTask15() } fun Shop.findAnyCustomerFrom(city: City): Customer? { // Return a customer who lives in the given city, or null if there is none - todoCollectionTask() + todoTask15() } diff --git a/src/ii_collections/_16_FlatMap.kt b/src/ii_collections/_16_FlatMap.kt index 85523c0a5..7977dcccc 100644 --- a/src/ii_collections/_16_FlatMap.kt +++ b/src/ii_collections/_16_FlatMap.kt @@ -1,18 +1,30 @@ package ii_collections fun example() { - val result = listOf("abc", "12").flatMap { it.toList() } - result == listOf('a', 'b', 'c', '1', '2') } +/** + * Description of task. + */ +fun todoTask16(): Nothing = util.TODO( + """ + Task 16 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + val Customer.orderedProducts: Set get() { // Return all products ordered by customer - todoCollectionTask() + todoTask16() } val Shop.allOrderedProducts: Set get() { // Return all products that were ordered by at least one customer - todoCollectionTask() + todoTask16() } diff --git a/src/ii_collections/_17_MaxMin.kt b/src/ii_collections/_17_MaxMin.kt index 78b09060b..88425d008 100644 --- a/src/ii_collections/_17_MaxMin.kt +++ b/src/ii_collections/_17_MaxMin.kt @@ -5,12 +5,26 @@ fun example4() { val longestString = listOf("a", "b").maxBy { it.length } } +/** + * Description of task. + */ +fun todoTask17(): Nothing = util.TODO( + """ + Task 17 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getCustomerWithMaximumNumberOfOrders(): Customer? { // Return a customer whose order count is the highest among all customers - todoCollectionTask() + todoTask17() } fun Customer.getMostExpensiveOrderedProduct(): Product? { // Return the most expensive product which has been ordered - todoCollectionTask() + todoTask17() } diff --git a/src/ii_collections/_18_Sort_.kt b/src/ii_collections/_18_Sort_.kt index 1bbbe4887..89385d934 100644 --- a/src/ii_collections/_18_Sort_.kt +++ b/src/ii_collections/_18_Sort_.kt @@ -2,11 +2,24 @@ package ii_collections fun example5() { val result = listOf("a", "bbb", "cc").sortedBy { it.length } - result == listOf("a", "cc", "bbb") } +/** + * Description of task. + */ +fun todoTask18(): Nothing = util.TODO( + """ + Task 18 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getCustomersSortedByNumberOfOrders(): List { // Return a list of customers, sorted by the ascending number of orders they made - todoCollectionTask() + todoTask18() } diff --git a/src/ii_collections/_19_Sum_.kt b/src/ii_collections/_19_Sum_.kt index f7c969f23..9c2480288 100644 --- a/src/ii_collections/_19_Sum_.kt +++ b/src/ii_collections/_19_Sum_.kt @@ -4,8 +4,22 @@ fun example6() { val sum = listOf(1, 5, 3).sum() } +/** + * Description of task. + */ +fun todoTask19(): Nothing = util.TODO( + """ + Task 19 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Customer.getTotalOrderPrice(): Double { // Return the sum of prices of all products that a customer has ordered. // Note: a customer may order the same product for several times. - todoCollectionTask() + todoTask19() } diff --git a/src/ii_collections/_20_GroupBy.kt b/src/ii_collections/_20_GroupBy.kt index dd364ea93..ee8396d6b 100644 --- a/src/ii_collections/_20_GroupBy.kt +++ b/src/ii_collections/_20_GroupBy.kt @@ -2,11 +2,24 @@ package ii_collections fun example7() { val result = listOf("a", "b", "ba", "ccc", "ad").groupBy { it.length } - result == mapOf(1 to listOf("a", "b"), 2 to listOf("ba", "ad"), 3 to listOf("ccc")) } +/** + * Description of task. + */ +fun todoTask20(): Nothing = util.TODO( + """ + Task 20 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.groupCustomersByCity(): Map> { // Return a map of the customers living in each city - todoCollectionTask() + todoTask20() } diff --git a/src/ii_collections/_21_Partition_.kt b/src/ii_collections/_21_Partition_.kt index f95b0da35..80c6849af 100644 --- a/src/ii_collections/_21_Partition_.kt +++ b/src/ii_collections/_21_Partition_.kt @@ -10,7 +10,21 @@ fun example8() { negative == listOf(-4, -11) } +/** + * Description of task. + */ +fun todoTask21(): Nothing = util.TODO( + """ + Task 21 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getCustomersWithMoreUndeliveredOrdersThanDelivered(): Set { // Return customers who have more undelivered orders than delivered - todoCollectionTask() + todoTask21() } diff --git a/src/ii_collections/_22_Fold_.kt b/src/ii_collections/_22_Fold_.kt index aa1a6d29c..07f9dfdc8 100644 --- a/src/ii_collections/_22_Fold_.kt +++ b/src/ii_collections/_22_Fold_.kt @@ -12,10 +12,23 @@ fun whatFoldDoes(): Int { return result } +/** + * Description of task. + */ +fun todoTask22(): Nothing = util.TODO( + """ + Task 22 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getSetOfProductsOrderedByEveryCustomer(): Set { // Return the set of products ordered by every customer - return customers.fold(allOrderedProducts, { - orderedByAll, customer -> - todoCollectionTask() + return customers.fold(/*allOrderedProducts*/ todoTask22(), { orderedByAll, customer -> + todoTask22() }) } diff --git a/src/ii_collections/_23_CompoundTasks.kt b/src/ii_collections/_23_CompoundTasks.kt index 35bd7eb7b..78740f6cb 100644 --- a/src/ii_collections/_23_CompoundTasks.kt +++ b/src/ii_collections/_23_CompoundTasks.kt @@ -1,18 +1,32 @@ package ii_collections +/** + * Description of task. + */ +fun todoTask23(): Nothing = util.TODO( + """ + Task 23 + + Task for working with collections. + Look through the 'Shop' API; all tasks are connected with it. + Return what is described in the name and the comment. + """, + references = { shop: Shop -> shop.customers } +) + fun Shop.getCustomersWhoOrderedProduct(product: Product): Set { // Return the set of customers who ordered the specified product - todoCollectionTask() + todoTask23() } fun Customer.getMostExpensiveDeliveredProduct(): Product? { // Return the most expensive product among all delivered products // (use the Order.isDelivered flag) - todoCollectionTask() + todoTask23() } fun Shop.getNumberOfTimesProductWasOrdered(product: Product): Int { // Return the number of times the given product was ordered. // Note: a customer may order the same product for several times. - todoCollectionTask() + todoTask23() } diff --git a/src/ii_collections/_24_ExtensionsOnCollections.kt b/src/ii_collections/_24_ExtensionsOnCollections.kt index 4311e0d64..67d817e65 100644 --- a/src/ii_collections/_24_ExtensionsOnCollections.kt +++ b/src/ii_collections/_24_ExtensionsOnCollections.kt @@ -2,13 +2,17 @@ package ii_collections import util.TODO +/** + * Description of task. + */ fun todoTask24(): Nothing = TODO( - """ - Task 24. - The function should behave the same as '_24_JavaCode.doSomethingStrangeWithCollection' + """ + Task 24 + + The function should behave the same as 'JavaCode24.doSomethingStrangeWithCollection' Replace all invocations of 'todoTask24()' with the appropriate code. - """, - references = { c: Collection -> _24_JavaCode().doSomethingStrangeWithCollection(c) } + """, + references = { c: Collection -> JavaCode24().doSomethingStrangeWithCollection(c) } ) fun doSomethingStrangeWithCollection(collection: Collection): Collection? { diff --git a/src/ii_collections/shop.kt b/src/ii_collections/shop.kt index 4d999e6ed..2aba781ce 100644 --- a/src/ii_collections/shop.kt +++ b/src/ii_collections/shop.kt @@ -1,5 +1,9 @@ package ii_collections +/** + * Pre-defined classes for tasks in ii_collections. + * DO NOT CHANGE THIS FILE. + */ data class Shop(val name: String, val customers: List) data class Customer(val name: String, val city: City, val orders: List) { diff --git a/src/ii_collections/todoUtil.kt b/src/ii_collections/todoUtil.kt deleted file mode 100644 index a497b66be..000000000 --- a/src/ii_collections/todoUtil.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ii_collections - -import util.TODO - -fun todoCollectionTask(): Nothing = TODO( - """ - Task for working with collections. - Look through the 'Shop' API; all tasks are connected with it. - Return what is described in the name and the comment. - - """, - references = { shop: Shop -> shop.customers } -) diff --git a/src/iii_conventions/MyDate.kt b/src/iii_conventions/MyDate.kt index 147cc3e78..7954cc35d 100644 --- a/src/iii_conventions/MyDate.kt +++ b/src/iii_conventions/MyDate.kt @@ -1,5 +1,10 @@ package iii_conventions +/** + * Pre-defined classes for tasks in iii_conventions + * DO NOT CHANGE THIS FILE. + */ + data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) operator fun MyDate.rangeTo(other: MyDate): DateRange = todoTask27() diff --git a/src/iii_conventions/MyDateUtil.kt b/src/iii_conventions/MyDateUtil.kt index 6594e5b3b..08cb78a9d 100644 --- a/src/iii_conventions/MyDateUtil.kt +++ b/src/iii_conventions/MyDateUtil.kt @@ -3,6 +3,11 @@ package iii_conventions import iii_conventions.TimeInterval.* import java.util.* +/** + * Pre-defined extension functions for the MyDate class for tasks in iii_conventions + * DO NOT CHANGE THIS FILE. + */ + fun MyDate.nextDay() = addTimeIntervals(DAY, 1) fun MyDate.addTimeIntervals(timeInterval: TimeInterval, number: Int): MyDate {