Skip to content

Commit

Permalink
Fix the last project (#190)
Browse files Browse the repository at this point in the history
* Fix the last project

* Add task remote info and fix naming
  • Loading branch information
nbirillo authored Dec 17, 2023
1 parent b14dcba commit 8c3d046
Show file tree
Hide file tree
Showing 77 changed files with 5,054 additions and 265 deletions.
2 changes: 1 addition & 1 deletion AlmostDone/CompleteTheProject/task-info.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
type: edu
custom_name: Console Photoshop - Finish The Game
custom_name: Console Photoshop - Finish The Application
files:
- name: test/Tests.kt
visible: false
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 929604042
id: 1988905602
2 changes: 1 addition & 1 deletion AlmostDone/choosePictureFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 868559526
id: 553514186
2 changes: 1 addition & 1 deletion AlmostDone/errorFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1498496671
id: 1629287997
2 changes: 1 addition & 1 deletion AlmostDone/letScopeFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1728990710
id: 1609671976
2 changes: 1 addition & 1 deletion AlmostDone/linesFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 496484521
id: 1298754091
2 changes: 1 addition & 1 deletion AlmostDone/multiRowStringsTheory/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 696102891
id: 965912956
2 changes: 1 addition & 1 deletion AlmostDone/nullSafetyTheory/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1028146491
id: 230726355
2 changes: 1 addition & 1 deletion AlmostDone/nullValue/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 519658693
id: 192844197
2 changes: 1 addition & 1 deletion AlmostDone/repeatFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1870873632
id: 1495658846
2 changes: 1 addition & 1 deletion AlmostDone/safeReadLineFunction/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1210033398
id: 2065245492
2 changes: 1 addition & 1 deletion AlmostDone/stringBuilder/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 1317807693
id: 223687468
2 changes: 1 addition & 1 deletion AlmostDone/whenTheory/task-remote-info.yaml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
id: 547369420
id: 957199675
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
package jetbrains.kotlin.course.last.push

// You will use this function later
fun getPattern(): String {
println(
"Do you want to use a pre-defined pattern or a custom one? " +
"Please input 'yes' for a pre-defined pattern or 'no' for a custom one"
)
do {
when (safeReadLine()) {
"yes" -> {
return choosePattern()
}
"no" -> {
println("Please, input a custom picture")
return safeReadLine()
}
else -> println("Please input 'yes' or 'no'")
}
} while (true)
}

// You will use this function later
fun choosePattern(): String {
do {
println("Please choose a pattern. The possible options: ${allPatterns().joinToString(", ")}")
val name = safeReadLine()
val pattern = getPatternByName(name)
pattern?.let {
return@choosePattern pattern
}
} while (true)
}

// You will use this function later
fun chooseGenerator(): String {
var toContinue = true
var generator = ""
println("Please choose the generator: 'canvas' or 'canvasGaps'.")
do {
when (val input = safeReadLine()) {
"canvas", "canvasGaps" -> {
toContinue = false
generator = input
}
else -> println("Please, input 'canvas' or 'canvasGaps'")
}
} while (toContinue)
return generator
}

// You will use this function later
fun safeReadLine(): String = readlnOrNull() ?: error("Your input is incorrect, sorry")

fun fillPatternRow(patternRow: String, patternWidth: Int) = if (patternRow.length <= patternWidth) {
val filledSpace = "$separator".repeat(patternWidth - patternRow.length)
"$patternRow$filledSpace"
Expand Down Expand Up @@ -77,8 +129,6 @@ fun addEmptyWindow(patternRow: String, patternWidth: Int, toAddAfter: Boolean =
}
}

fun isEmpty(pattern: String) = pattern == ""

fun repeatHorizontallyWithGaps(pattern: String, n: Int, toAddSeparatorAfter: Boolean): String {
val pictureRows = pattern.lines()
val patternWidth = getPatternWidth(pattern)
Expand All @@ -89,12 +139,12 @@ fun repeatHorizontallyWithGaps(pattern: String, n: Int, toAddSeparatorAfter: Boo
val currentRwSb = StringBuilder()
val currentWidth = makeEvenNumber(n) / 2
val patternToRepeat = addEmptyWindow(currentRow, patternWidth, toAddSeparatorAfter).repeat(currentWidth)
if (isEmpty(patternToRepeat)) {
if (patternToRepeat.isEmpty()) {
currentRwSb.append(currentRow)
} else {
currentRwSb.append(patternToRepeat)
}
if (n % 2 != 0 && !isEmpty(patternToRepeat)) {
if (n % 2 != 0 && patternToRepeat.isNotEmpty()) {
currentRwSb.append(patternToRepeat.dropLast(patternToRepeat.length - currentRow.length))
}
sb.append(currentRwSb.toString())
Expand All @@ -110,5 +160,17 @@ fun canvasWithGapsGenerator(pattern: String, width: Int, height: Int): String {
}

fun main() {
// Write your code here
// Uncomment this code on the last step of the game

// val pattern = getPattern()
// val generatorName = chooseGenerator()
// println("Please input the width of the resulting picture:")
// val width = safeReadLine().toInt()
// println("Please input the height of the resulting picture:")
// val height = safeReadLine().toInt()

// println("The pattern:$newLineSymbol${pattern.trimIndent()}")

// println("The generated image:")
// println(applyGenerator(pattern, generatorName, width, height))
}
40 changes: 21 additions & 19 deletions LastPush/CanvasGapsGenerator/task-info.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
type: edu
custom_name: Canvas gaps generator
custom_name: Patterns Generator - canvasWithGapsGenerator Function
files:
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/Main.kt
visible: true
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/Patterns.kt
visible: false
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/PreDefinedSymbols.kt
visible: false
- name: test/CanvasGenerator.kt
visible: false
- name: test/CanvasWithGapsGenerator.kt
visible: false
- name: test/Helpers.kt
visible: false
- name: test/PatternsGeneratorTestsUtils.kt
visible: false
- name: test/Tests.kt
visible: false
- name: test/MainClass.kt
visible: false
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/Main.kt
visible: true
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/Patterns.kt
visible: false
- name: src/main/kotlin/jetbrains/kotlin/course/last/push/PreDefinedSymbols.kt
visible: false
- name: test/CanvasGenerator.kt
visible: false
- name: test/CanvasWithGapsGenerator.kt
visible: false
- name: test/Helpers.kt
visible: false
- name: test/PatternsGeneratorTestsUtils.kt
visible: false
- name: test/Tests.kt
visible: false
- name: test/MainClass.kt
visible: false
- name: test/DropTopLine.kt
visible: false
feedback_link: https://docs.google.com/forms/d/e/1FAIpQLScylICclQIi9_YDjO7iuyRITDLn0Qgzw_aLxKxiishKAbL0qg/viewform?usp=pp_url&entry.2103429047=Introduction/Last+push/Canvas+gaps+generator
29 changes: 21 additions & 8 deletions LastPush/CanvasGapsGenerator/task.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
This step is not easy, but we believe you will solve it!

### Task

On this step you need to implement the `canvasWithGapsGenerator` function, which accepts the `pattern`, `width`, and `height` that were inputted by the user.
This function should return a new string with a generated canvas-with-gaps picture.

<div class="hint" title="Push me to see the new signature of the canvasWithGapsGenerator function">

The signature of the function is:
```kotlin
fun canvasWithGapsGenerator(pattern: String, width: Int, height: Int): String
```
</div>

The `canvasGaps` generator should build a rectangle `width` x `height` from the pattern,
while leaving gaps instead of every other element.
The generator works according to the following algorithm:
Expand All @@ -11,7 +23,7 @@ The generator works according to the following algorithm:
and in every **even level** - in **odd**;
4) When repeated **vertically**, the pattern remains **unchanged**.

<div class="hint" title="The `canvasGaps` filter examples">
<div class="hint" title="Push me to see the `canvasGaps` filter examples">
For example, let's take the pattern:

```text
Expand Down Expand Up @@ -59,7 +71,7 @@ If you have any difficulties, **hints will help you solve this task**.

### Hints

<div class="hint" title="The `dropLast` built-in function">
<div class="hint" title="Push me to learn about the `dropLast` built-in function">

To drop <code>n</code> last symbols from a <code>String</code>, you can use the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/drop-last.html"><code>dropLast</code></a> function, e.g.:
```kotlin
Expand All @@ -69,10 +81,11 @@ To drop <code>n</code> last symbols from a <code>String</code>, you can use the
If you need to drop <code>n</code> symbols from the beginning of a <code>String</code>, you can use the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/drop.html"><code>drop</code></a> function.
</div>

<div class="hint" title="Code style hint">
In industrial programming, duplicate code is commonly avoided and put into functions.
However, it is not always possible to immediately write clear and readable code.
Try implementing the <code>canvasGenerator</code> and <code>canvasWithGapsGenerator</code> functions
so that they pass all the tests and then start improving the code.
This process is called <i>refactoring</i>.
<div class="hint" title="Push me to get a code style hint">

In industrial programming, duplicate code is commonly avoided and put into functions.
However, it is not always possible to immediately write clear and readable code.
Try implementing the <code>canvasGenerator</code> and <code>canvasWithGapsGenerator</code> functions
so that they pass all the tests and then start improving the code.
This process is called <i>refactoring</i>.
</div>
21 changes: 21 additions & 0 deletions LastPush/CanvasGapsGenerator/test/CanvasGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,27 @@ internal val canvasGeneratorMethod = TestMethod(
),
)

internal val repeatHorizontallyMethod = TestMethod(
"repeatHorizontally",
TestKotlinType("String"),
listOf(
TestVariable("pattern", "String"),
TestVariable("n", "Int"),
TestVariable("patternWidth", "Int"),
),
)

internal val dropTopFromLineMethod = TestMethod(
"dropTopFromLine",
TestKotlinType("String"),
listOf(
TestVariable("line", "String"),
TestVariable("width", "Int"),
TestVariable("patternHeight", "Int"),
TestVariable("patternWidth", "Int"),
),
)

internal fun canvas() = Pattern.values()
.flatMap { f -> f.canvasFilters.map { f.pattern to it } }

Expand Down
32 changes: 32 additions & 0 deletions LastPush/CanvasGapsGenerator/test/DropTopLine.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import jetbrains.kotlin.course.last.push.ball
import jetbrains.kotlin.course.last.push.cube
import jetbrains.kotlin.course.last.push.robot
import org.junit.jupiter.params.provider.Arguments


internal val dropTopLineData = listOf(
// pattern, expected
Arguments.of(
ball, ball
),
Arguments.of(
robot,
"""
| o o |
| ^ |
| --- |
+---+---+
""".trimIndent()
),
Arguments.of(
cube,
"""
.' | .'|
+---+--+' |
| | | |
| ,+--+---+
|.' | .'
+------+'
""".trimIndent()
),
)
2 changes: 2 additions & 0 deletions LastPush/CanvasGapsGenerator/test/MainClass.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ internal val mainClass = TestClass(
canvasGeneratorMethod,
fillPatternRowMethod,
getPatternHeightMethod,
repeatHorizontallyMethod,
dropTopFromLineMethod
),
)
52 changes: 52 additions & 0 deletions LastPush/CanvasGapsGenerator/test/Tests.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import jetbrains.kotlin.course.last.push.ball
import jetbrains.kotlin.course.last.push.getPatternHeight
import jetbrains.kotlin.course.last.push.getPatternWidth
import jetbrains.kotlin.course.last.push.newLineSymbol
import org.jetbrains.academy.test.system.core.invokeWithArgs
import org.jetbrains.academy.test.system.core.models.classes.findClassSafe
Expand Down Expand Up @@ -32,6 +34,14 @@ class Test {
fun beforeAll() {
mainClazz = mainClass.findClassSafe() ?: throwInternalCourseError()
}

@JvmStatic
fun dropTopLineDataArguments() = dropTopLineData

@JvmStatic
fun repeatHorizontallyArguments() = canvas().filter{ (p, f) ->
f.height == 1
}.toArguments()
}

@Test
Expand All @@ -50,6 +60,48 @@ class Test {
)
}

@Test
fun dropTopFromLineFunction() {
mainClass.checkMethod(mainClazz, dropTopFromLineMethod)
}

@ParameterizedTest
@MethodSource("dropTopLineDataArguments")
fun dropTopFromLineFunctionImplementation(
line: String,
expected: String
) {
val userMethod = mainClass.findMethod(mainClazz, dropTopFromLineMethod)
val patternWidth = getPatternWidth(line)
val patternHeight = getPatternHeight(line)
val actualResult = userMethod.invokeWithArgs(line, 1, patternHeight, patternWidth, clazz = mainClazz).toString()
val error = "The method ${dropTopFromLineMethod.name} with arguments line=${newLineSymbol}$line${newLineSymbol}, width=1, patternHeight=$patternHeight, patternWidth=$patternWidth should return$newLineSymbol$expected${newLineSymbol}But it returns$newLineSymbol$actualResult"
Assertions.assertEquals(
expected.removeSuffix(System.lineSeparator()),
actualResult.removeSuffix(System.lineSeparator())
) { error }
}

@Test
fun repeatHorizontallyFunction() {
mainClass.checkMethod(mainClazz, repeatHorizontallyMethod)
}

@ParameterizedTest
@MethodSource("repeatHorizontallyArguments")
fun repeatHorizontallyFunctionImplementation(
pattern: String,
canvasFilter: Filter
) {
val userMethod = mainClass.findMethod(mainClazz, repeatHorizontallyMethod)
val patternWidth = getPatternWidth(pattern)
val actualResult = userMethod.invokeWithArgs(pattern, canvasFilter.width, patternWidth, clazz = mainClazz).toString()
Assertions.assertEquals(
canvasFilter.result.removeSuffix(System.lineSeparator()),
actualResult.removeSuffix(System.lineSeparator())
) { "The method ${repeatHorizontallyMethod.name} with arguments pattern=$pattern, n=${canvasFilter.width}, patternWidth=$patternWidth should return:${System.lineSeparator()}${canvasFilter.result}${System.lineSeparator()}But it returns:${System.lineSeparator()}$actualResult" }
}

@Test
fun canvasGeneratorFunction() {
mainClass.checkMethod(mainClazz, canvasGeneratorMethod)
Expand Down
Loading

0 comments on commit 8c3d046

Please sign in to comment.