diff --git a/.github/workflows/validate-pr-metadata.yml b/.github/workflows/validate-pr-metadata.yml index 10ef3c7..6fa2e1d 100644 --- a/.github/workflows/validate-pr-metadata.yml +++ b/.github/workflows/validate-pr-metadata.yml @@ -1,9 +1,8 @@ -name: Validate PR Metadata +name: Validate PR Metadata and Check SDC-Tools Tasks on: - pull_request_target: + pull_request: types: - labeled - - unlabeled - opened - edited - reopened @@ -16,3 +15,62 @@ jobs: - uses: CodeYourFuture/actions/validate-pr-metadata@main with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + test_sdc_tasks: + name: Test SDC Tasks + runs-on: ubuntu-slim + permissions: + pull-requests: write + if: ${{ github.event.label.name == 'Needs Review' }} + steps: + - name: checkout base branch + uses: actions/checkout@v5 + - name: Get changed files + id: changed-files + uses: tj-actions/changed-files@v47.0.5 + - name: test individual shell tools + id: test-individual-shell-tools + if: contains(steps.changed-files.outputs.modified_files, 'individual-shell-tools/') + run: ./test-sdc.sh individual-shell-tools + shell: bash + - name: test jq + id: test-jq + if: contains(steps.changed-files.outputs.modified_files, 'jq/') + run: ./test-sdc.sh jq + shell: bash + - name: test shell-pipelines + id: test-shell-pipelines + if: contains(steps.changed-files.outputs.modified_files, 'shell-pipelines/') + run: ./test-sdc.sh shell-pipelines + shell: bash + - name: test number-systems + id: test-number-systems + if: contains(steps.changed-files.outputs.modified_files, 'number-systems/') + run: ./test-sdc.sh number-systems + shell: bash + - name: test implement-cowsay + id: test-implement-cowsay + if: contains(steps.changed-files.outputs.all_modified_files, 'implement-cowsay/') + run: ./test-sdc.sh implement-cowsay + shell: bash + - name: make output comment + if: steps.test-individual-shell-tools.outputs.attempted == 'y' || steps.test-jq.outputs.attempted == 'y' || steps.test-shell-pipelines.outputs.attempted == 'y' || steps.test-number-systems.outputs.attempted == 'y' || steps.test-implement-cowsay.outputs.attempted == 'y' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE_URL: ${{ github.event.pull_request.html_url }} + run: | + gh release -R CodeYourFuture/trainee-tracker view --json assets -q ".assets[] | select(.name | startswith(\"pr-metadata-validator-musl-\")).url" | xargs curl --fail -L -o /tmp/pr-metadata-validator && chmod 0755 /tmp/pr-metadata-validator + /tmp/pr-metadata-validator --only-close-existing-comments-with-tag="sdc-test-results" "${ISSUE_URL}" + gh pr comment $ISSUE_URL --body-file testoutput.txt + - name: add appropriate labels + if: steps.test-individual-shell-tools.outputs.complete == 'y' || steps.test-jq.outputs.complete == 'y' || steps.test-shell-pipelines.outputs.complete == 'y' || steps.test-implement-cowsay.outputs.complete == 'y' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ISSUE_URL: ${{ github.event.pull_request.html_url }} + run: | + gh pr edit $ISSUE_URL --add-label "Complete" + gh pr edit $ISSUE_URL --remove-label "Needs Review" + - name: fail if not complete + if: (steps.test-individual-shell-tools.outputs.attempted == 'y' || steps.test-jq.outputs.attempted == 'y' || steps.test-shell-pipelines.outputs.attempted == 'y' || steps.test-implement-cowsay.outputs.attempted == 'y') && !(steps.test-individual-shell-tools.outputs.complete == 'y' || steps.test-jq.outputs.complete == 'y' || steps.test-shell-pipelines.outputs.complete == 'y' || steps.test-implement-cowsay.outputs.complete == 'y') + run: | + exit -1 diff --git a/.gitignore b/.gitignore index 3c3629e..63db17d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ node_modules +testoutput.txt +.venv +__pycache__ +.mypy_cache \ No newline at end of file diff --git a/expect/implement-cowsay/cow-grass.txt b/expect/implement-cowsay/cow-grass.txt new file mode 100644 index 0000000..d9c665a --- /dev/null +++ b/expect/implement-cowsay/cow-grass.txt @@ -0,0 +1,10 @@ + ________________ +| Grass, delicious | + ================ + \ + \ + ^__^ + (oo)\_______ + (__)\ )\/\ + ||----w | + || || diff --git a/expect/implement-cowsay/turtle-fish.txt b/expect/implement-cowsay/turtle-fish.txt new file mode 100644 index 0000000..5dadfa0 --- /dev/null +++ b/expect/implement-cowsay/turtle-fish.txt @@ -0,0 +1,22 @@ + ______________ +| Fish are cool! | + ============== + \ + \ + \ + \ + ___-------___ + _-~~ ~~-_ + _-~ /~-_ + /^\__/^\ /~ \ / \ + /| O|| O| / \_______________/ \ + | |___||__| / / \ \ + | \ / / \ \ + | (_______) /______/ \_________ \ + | / / \ / \ + \ \^\\ \ / \ / + \ || \______________/ _-_ //\__// + \ ||------_-~~-_ ------------- \ --/~ ~\ || __/ + ~-----||====/~ |==================| |/~~~~~ + (_(__/ ./ / \_\ \. + (_(___/ \_____)_) diff --git a/expect/individual-shell-tools/awk/script-01.sh b/expect/individual-shell-tools/awk/script-01.sh new file mode 100755 index 0000000..050f043 --- /dev/null +++ b/expect/individual-shell-tools/awk/script-01.sh @@ -0,0 +1,6 @@ +Ahmed +Basia +Mehmet +Leila +Piotr +Chandra diff --git a/expect/individual-shell-tools/awk/script-02.sh b/expect/individual-shell-tools/awk/script-02.sh new file mode 100755 index 0000000..ee7e0fe --- /dev/null +++ b/expect/individual-shell-tools/awk/script-02.sh @@ -0,0 +1,6 @@ +Ahmed London +Basia London +Mehmet Birmingham +Leila London +Piotr Glasgow +Chandra Birmingham diff --git a/expect/individual-shell-tools/awk/script-03.sh b/expect/individual-shell-tools/awk/script-03.sh new file mode 100755 index 0000000..f5d0b1f --- /dev/null +++ b/expect/individual-shell-tools/awk/script-03.sh @@ -0,0 +1,6 @@ +Ahmed 1 +Basia 22 +Mehmet 3 +Leila 1 +Piotr 15 +Chandra 12 diff --git a/expect/individual-shell-tools/awk/script-04.sh b/expect/individual-shell-tools/awk/script-04.sh new file mode 100755 index 0000000..6e95a2f --- /dev/null +++ b/expect/individual-shell-tools/awk/script-04.sh @@ -0,0 +1,3 @@ +Ahmed 4 +Basia 6 +Leila 1 diff --git a/expect/individual-shell-tools/awk/script-05.sh b/expect/individual-shell-tools/awk/script-05.sh new file mode 100755 index 0000000..dd7e1d3 --- /dev/null +++ b/expect/individual-shell-tools/awk/script-05.sh @@ -0,0 +1,6 @@ +Ahmed 3 +Basia 3 +Mehmet 3 +Leila 1 +Piotr 5 +Chandra 2 diff --git a/expect/individual-shell-tools/awk/script-06-stretch.sh b/expect/individual-shell-tools/awk/script-06-stretch.sh new file mode 100755 index 0000000..fb1e7bc --- /dev/null +++ b/expect/individual-shell-tools/awk/script-06-stretch.sh @@ -0,0 +1 @@ +54 diff --git a/expect/individual-shell-tools/awk/script-07-stretch.sh b/expect/individual-shell-tools/awk/script-07-stretch.sh new file mode 100755 index 0000000..33ff777 --- /dev/null +++ b/expect/individual-shell-tools/awk/script-07-stretch.sh @@ -0,0 +1,6 @@ +Ahmed 15 +Basia 37 +Mehmet 32 +Leila 1 +Piotr 61 +Chandra 18 diff --git a/expect/individual-shell-tools/cat/script-01.sh b/expect/individual-shell-tools/cat/script-01.sh new file mode 100755 index 0000000..ed7bf7d --- /dev/null +++ b/expect/individual-shell-tools/cat/script-01.sh @@ -0,0 +1 @@ +Once upon a time... diff --git a/expect/individual-shell-tools/cat/script-02.sh b/expect/individual-shell-tools/cat/script-02.sh new file mode 100755 index 0000000..769b7e0 --- /dev/null +++ b/expect/individual-shell-tools/cat/script-02.sh @@ -0,0 +1,5 @@ +Once upon a time... +There was a house made of gingerbread. +It looked delicious. +I was tempted to take a bite of it. +But this seemed like a bad idea... diff --git a/expect/individual-shell-tools/cat/script-03.sh b/expect/individual-shell-tools/cat/script-03.sh new file mode 100755 index 0000000..f97bd50 --- /dev/null +++ b/expect/individual-shell-tools/cat/script-03.sh @@ -0,0 +1,3 @@ + 1 It looked delicious. + 2 I was tempted to take a bite of it. + 3 But this seemed like a bad idea... diff --git a/expect/individual-shell-tools/cat/script-04-stretch.sh b/expect/individual-shell-tools/cat/script-04-stretch.sh new file mode 100755 index 0000000..6f35e89 --- /dev/null +++ b/expect/individual-shell-tools/cat/script-04-stretch.sh @@ -0,0 +1,5 @@ + 1 Once upon a time... + 2 There was a house made of gingerbread. + 3 It looked delicious. + 4 I was tempted to take a bite of it. + 5 But this seemed like a bad idea... diff --git a/expect/individual-shell-tools/grep/script-01.sh b/expect/individual-shell-tools/grep/script-01.sh new file mode 100755 index 0000000..bc96ffe --- /dev/null +++ b/expect/individual-shell-tools/grep/script-01.sh @@ -0,0 +1,6 @@ +Doctor: Hello +Doctor: What's wrong today? +Doctor: That sounds frustrating. When did this start? +Doctor: Say "Hi". +Doctor: You didn't say hello +Doctor: You're welcome, goodbye diff --git a/expect/individual-shell-tools/grep/script-02.sh b/expect/individual-shell-tools/grep/script-02.sh new file mode 100755 index 0000000..bad606e --- /dev/null +++ b/expect/individual-shell-tools/grep/script-02.sh @@ -0,0 +1,9 @@ +Doctor: Hello +Patient: Hello Doctor +Doctor: What's wrong today? +Doctor: That sounds frustrating. When did this start? +Doctor: Say "Hi". +Doctor: You didn't say hello +Doctor: You're welcome, goodbye +Patient: I went to the doctor! +Spouse: I'm glad you saw the Doctor: did they cure you? diff --git a/expect/individual-shell-tools/grep/script-03.sh b/expect/individual-shell-tools/grep/script-03.sh new file mode 100755 index 0000000..ec63514 --- /dev/null +++ b/expect/individual-shell-tools/grep/script-03.sh @@ -0,0 +1 @@ +9 diff --git a/expect/individual-shell-tools/grep/script-04.sh b/expect/individual-shell-tools/grep/script-04.sh new file mode 100755 index 0000000..5814afa --- /dev/null +++ b/expect/individual-shell-tools/grep/script-04.sh @@ -0,0 +1,10 @@ +Doctor: What's wrong today? +Doctor: That sounds frustrating. When did this start? +Doctor: Say "Hi". +Patient: Hi +Patient: I seem to be cured! +Doctor: You're welcome, goodbye + +Patient: I went to the doctor! +Spouse: I'm glad you saw the Doctor: did they cure you? +Patient: Yes! diff --git a/expect/individual-shell-tools/grep/script-05.sh b/expect/individual-shell-tools/grep/script-05.sh new file mode 100755 index 0000000..2ed07ed --- /dev/null +++ b/expect/individual-shell-tools/grep/script-05.sh @@ -0,0 +1,5 @@ +Doctor: You didn't say hello +Patient: I seem to be cured! +-- +Patient: I went to the doctor! +Spouse: I'm glad you saw the Doctor: did they cure you? diff --git a/expect/individual-shell-tools/grep/script-06.sh b/expect/individual-shell-tools/grep/script-06.sh new file mode 100755 index 0000000..87b3a4f --- /dev/null +++ b/expect/individual-shell-tools/grep/script-06.sh @@ -0,0 +1,2 @@ +dialogue-2.txt +dialogue.txt diff --git a/expect/individual-shell-tools/grep/script-07.sh b/expect/individual-shell-tools/grep/script-07.sh new file mode 100755 index 0000000..aed78c6 --- /dev/null +++ b/expect/individual-shell-tools/grep/script-07.sh @@ -0,0 +1,3 @@ +dialogue-2.txt:2 +dialogue-3.txt:0 +dialogue.txt:6 diff --git a/expect/individual-shell-tools/ls/script-01.sh b/expect/individual-shell-tools/ls/script-01.sh new file mode 100755 index 0000000..dd590d6 --- /dev/null +++ b/expect/individual-shell-tools/ls/script-01.sh @@ -0,0 +1,5 @@ +child-directory +script-01.sh +script-02.sh +script-03.sh +script-04.sh diff --git a/expect/individual-shell-tools/ls/script-02.sh b/expect/individual-shell-tools/ls/script-02.sh new file mode 100755 index 0000000..bfd087e --- /dev/null +++ b/expect/individual-shell-tools/ls/script-02.sh @@ -0,0 +1,3 @@ +helper-1.txt +helper-2.txt +helper-3.txt diff --git a/expect/individual-shell-tools/ls/script-03.sh b/expect/individual-shell-tools/ls/script-03.sh new file mode 100755 index 0000000..36acd71 --- /dev/null +++ b/expect/individual-shell-tools/ls/script-03.sh @@ -0,0 +1,11 @@ +.: +child-directory +script-01.sh +script-02.sh +script-03.sh +script-04.sh + +./child-directory: +helper-1.txt +helper-2.txt +helper-3.txt diff --git a/expect/individual-shell-tools/ls/script-04.sh b/expect/individual-shell-tools/ls/script-04.sh new file mode 100755 index 0000000..86e7570 --- /dev/null +++ b/expect/individual-shell-tools/ls/script-04.sh @@ -0,0 +1,8 @@ +First exercise (sorted newest to oldest): +helper-3.txt +helper-1.txt +helper-2.txt +Second exercise (sorted oldest to newest): +helper-2.txt +helper-1.txt +helper-3.txt diff --git a/expect/individual-shell-tools/sed/script-01.sh b/expect/individual-shell-tools/sed/script-01.sh new file mode 100755 index 0000000..d92b03a --- /dev/null +++ b/expect/individual-shell-tools/sed/script-01.sh @@ -0,0 +1,11 @@ +ThIs Is a sample fIle for experImentIng wIth sed. + +It contaIns many lInes, and there are some thIngs you may want to do wIth each of them. + +We'll Include some score InformatIon: +37 AlIsha +15 Jacob +7 PIetro +3 Katya + +We also should remember, when we go shoppIng, to get 4 Items: oranges,cheese,bread,olIves. diff --git a/expect/individual-shell-tools/sed/script-02.sh b/expect/individual-shell-tools/sed/script-02.sh new file mode 100755 index 0000000..e326bd4 --- /dev/null +++ b/expect/individual-shell-tools/sed/script-02.sh @@ -0,0 +1,11 @@ +This is a sample file for experimenting with sed. + +It contains many lines, and there are some things you may want to do with each of them. + +We'll include some score information: + Alisha + Jacob + Pietro + Katya + +We also should remember, when we go shopping, to get items: oranges,cheese,bread,olives. diff --git a/expect/individual-shell-tools/sed/script-03.sh b/expect/individual-shell-tools/sed/script-03.sh new file mode 100755 index 0000000..088b17d --- /dev/null +++ b/expect/individual-shell-tools/sed/script-03.sh @@ -0,0 +1,6 @@ +This is a sample file for experimenting with sed. + +It contains many lines, and there are some things you may want to do with each of them. + +We'll include some score information: + diff --git a/expect/individual-shell-tools/sed/script-04.sh b/expect/individual-shell-tools/sed/script-04.sh new file mode 100755 index 0000000..852fa15 --- /dev/null +++ b/expect/individual-shell-tools/sed/script-04.sh @@ -0,0 +1,11 @@ +This is a sample file for experimenting with sed. + +It contains many lines, and there are some things you may want to do with each of them. + +We'll include some score information: +37 Alisha +15 Jacob +7 Pietro +3 Katya + +We also should remember, when we go shopping, to get 4 items: oranges,cheese,bread,olives. diff --git a/expect/individual-shell-tools/sed/script-05.sh b/expect/individual-shell-tools/sed/script-05.sh new file mode 100755 index 0000000..fe4d9d1 --- /dev/null +++ b/expect/individual-shell-tools/sed/script-05.sh @@ -0,0 +1,11 @@ +This is a sample file for experimenting with sed. + +It contains many lines, and there are some things you may want to do with each of them. + +We'll include some score information: +Alisha 37 +Jacob 15 +Pietro 7 +Katya 3 + +We also should remember, when we go shopping, to get 4 items: oranges,cheese,bread,olives. diff --git a/expect/individual-shell-tools/sed/script-06.sh b/expect/individual-shell-tools/sed/script-06.sh new file mode 100755 index 0000000..d9f950f --- /dev/null +++ b/expect/individual-shell-tools/sed/script-06.sh @@ -0,0 +1,11 @@ +This is a sample file for experimenting with sed. + +It contains many lines, and there are some things you may want to do with each of them. + +We'll include some score information: +37 Alisha +15 Jacob +7 Pietro +3 Katya + +We also should remember, when we go shopping, to get 4 items: oranges, cheese, bread, olives. diff --git a/expect/individual-shell-tools/wc/script-01.sh b/expect/individual-shell-tools/wc/script-01.sh new file mode 100755 index 0000000..d1ad53e --- /dev/null +++ b/expect/individual-shell-tools/wc/script-01.sh @@ -0,0 +1 @@ +19 ../helper-files/helper-3.txt diff --git a/expect/individual-shell-tools/wc/script-02.sh b/expect/individual-shell-tools/wc/script-02.sh new file mode 100755 index 0000000..6bd060b --- /dev/null +++ b/expect/individual-shell-tools/wc/script-02.sh @@ -0,0 +1 @@ +3 ../helper-files/helper-3.txt diff --git a/expect/individual-shell-tools/wc/script-03.sh b/expect/individual-shell-tools/wc/script-03.sh new file mode 100755 index 0000000..572716a --- /dev/null +++ b/expect/individual-shell-tools/wc/script-03.sh @@ -0,0 +1,4 @@ + 1 4 20 ../helper-files/helper-1.txt + 1 7 39 ../helper-files/helper-2.txt + 3 19 92 ../helper-files/helper-3.txt + 5 30 151 total diff --git a/expect/jq/script-01.sh b/expect/jq/script-01.sh new file mode 100755 index 0000000..e16f4ed --- /dev/null +++ b/expect/jq/script-01.sh @@ -0,0 +1 @@ +Selma diff --git a/expect/jq/script-02.sh b/expect/jq/script-02.sh new file mode 100755 index 0000000..18711af --- /dev/null +++ b/expect/jq/script-02.sh @@ -0,0 +1 @@ +35 Fashion Street, London, E1 6PX diff --git a/expect/jq/script-03.sh b/expect/jq/script-03.sh new file mode 100755 index 0000000..d63f6ec --- /dev/null +++ b/expect/jq/script-03.sh @@ -0,0 +1,2 @@ +Selma, Software Engineer +Selma, Software Engineer diff --git a/expect/jq/script-04.sh b/expect/jq/script-04.sh new file mode 100755 index 0000000..050f043 --- /dev/null +++ b/expect/jq/script-04.sh @@ -0,0 +1,6 @@ +Ahmed +Basia +Mehmet +Leila +Piotr +Chandra diff --git a/expect/jq/script-05.sh b/expect/jq/script-05.sh new file mode 100755 index 0000000..ee7e0fe --- /dev/null +++ b/expect/jq/script-05.sh @@ -0,0 +1,6 @@ +Ahmed London +Basia London +Mehmet Birmingham +Leila London +Piotr Glasgow +Chandra Birmingham diff --git a/expect/jq/script-06.sh b/expect/jq/script-06.sh new file mode 100755 index 0000000..f5d0b1f --- /dev/null +++ b/expect/jq/script-06.sh @@ -0,0 +1,6 @@ +Ahmed 1 +Basia 22 +Mehmet 3 +Leila 1 +Piotr 15 +Chandra 12 diff --git a/expect/jq/script-07.sh b/expect/jq/script-07.sh new file mode 100755 index 0000000..59c783f --- /dev/null +++ b/expect/jq/script-07.sh @@ -0,0 +1,6 @@ +Ahmed 4 +Basia 6 +Mehmet 17 +Leila 1 +Piotr 8 +Chandra 6 diff --git a/expect/jq/script-08.sh b/expect/jq/script-08.sh new file mode 100755 index 0000000..dd7e1d3 --- /dev/null +++ b/expect/jq/script-08.sh @@ -0,0 +1,6 @@ +Ahmed 3 +Basia 3 +Mehmet 3 +Leila 1 +Piotr 5 +Chandra 2 diff --git a/expect/jq/script-09.sh b/expect/jq/script-09.sh new file mode 100755 index 0000000..33ff777 --- /dev/null +++ b/expect/jq/script-09.sh @@ -0,0 +1,6 @@ +Ahmed 15 +Basia 37 +Mehmet 32 +Leila 1 +Piotr 61 +Chandra 18 diff --git a/expect/jq/script-10.sh b/expect/jq/script-10.sh new file mode 100755 index 0000000..fb1e7bc --- /dev/null +++ b/expect/jq/script-10.sh @@ -0,0 +1 @@ +54 diff --git a/expect/jq/script-11.sh b/expect/jq/script-11.sh new file mode 100755 index 0000000..4e9bdff --- /dev/null +++ b/expect/jq/script-11.sh @@ -0,0 +1 @@ +164 diff --git a/expect/number-systems/Part-1.json b/expect/number-systems/Part-1.json new file mode 100644 index 0000000..d96c538 --- /dev/null +++ b/expect/number-systems/Part-1.json @@ -0,0 +1 @@ +{"answers": [0, 1110, 45, 1000, "01011", 11111, 100010, 15, 8, 2, "(10$|10[^0-9])", "E", 182, 902, 11, 33]} diff --git a/expect/shell-pipelines/ls-grep/script-01.sh b/expect/shell-pipelines/ls-grep/script-01.sh new file mode 100755 index 0000000..5481774 --- /dev/null +++ b/expect/shell-pipelines/ls-grep/script-01.sh @@ -0,0 +1,11 @@ +Ariane +Daniel +HoChiMinh +KualaLumpur +Levi +London +NewYork +Niamh +Olga +York +dHondt diff --git a/expect/shell-pipelines/ls-grep/script-02.sh b/expect/shell-pipelines/ls-grep/script-02.sh new file mode 100755 index 0000000..35f2e44 --- /dev/null +++ b/expect/shell-pipelines/ls-grep/script-02.sh @@ -0,0 +1,10 @@ +Ariane +Daniel +HoChiMinh +KualaLumpur +Levi +London +NewYork +Niamh +Olga +York diff --git a/expect/shell-pipelines/ls-grep/script-03.sh b/expect/shell-pipelines/ls-grep/script-03.sh new file mode 100755 index 0000000..37ec450 --- /dev/null +++ b/expect/shell-pipelines/ls-grep/script-03.sh @@ -0,0 +1,7 @@ +Ariane +Daniel +Levi +London +Niamh +Olga +York diff --git a/expect/shell-pipelines/ls-grep/script-04.sh b/expect/shell-pipelines/ls-grep/script-04.sh new file mode 100755 index 0000000..7f8f011 --- /dev/null +++ b/expect/shell-pipelines/ls-grep/script-04.sh @@ -0,0 +1 @@ +7 diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-01.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-01.sh new file mode 100755 index 0000000..a622bc9 --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-01.sh @@ -0,0 +1,6 @@ +Ahmed London 1 10 4 +Basia London 22 9 6 +Chandra Birmingham 12 6 +Leila London 1 +Mehmet Birmingham 3 12 17 +Piotr Glasgow 15 2 25 11 8 diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-02.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-02.sh new file mode 100755 index 0000000..c560f60 --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-02.sh @@ -0,0 +1,6 @@ +Basia London 22 9 6 +Piotr Glasgow 15 2 25 11 8 +Chandra Birmingham 12 6 +Mehmet Birmingham 3 12 17 +Leila London 1 +Ahmed London 1 10 4 diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-03.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-03.sh new file mode 100755 index 0000000..52d05bc --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-03.sh @@ -0,0 +1,3 @@ +Basia London 22 9 6 +Piotr Glasgow 15 2 25 11 8 +Chandra Birmingham 12 6 diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-04.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-04.sh new file mode 100755 index 0000000..9c18f93 --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-04.sh @@ -0,0 +1 @@ +Piotr Glasgow 15 2 25 11 8 diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-05.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-05.sh new file mode 100755 index 0000000..5b6440e --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-05.sh @@ -0,0 +1,6 @@ +Entry German +Entry Mariana +Entry Sally +Exit German +Exit Mariana +Exit Sally diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-06.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-06.sh new file mode 100755 index 0000000..93bd06b --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-06.sh @@ -0,0 +1,2 @@ + 5 Entry + 4 Exit diff --git a/expect/shell-pipelines/sort-uniq-head-tail/script-07.sh b/expect/shell-pipelines/sort-uniq-head-tail/script-07.sh new file mode 100755 index 0000000..93bd06b --- /dev/null +++ b/expect/shell-pipelines/sort-uniq-head-tail/script-07.sh @@ -0,0 +1,2 @@ + 5 Entry + 4 Exit diff --git a/expect/shell-pipelines/tr/script-01.sh b/expect/shell-pipelines/tr/script-01.sh new file mode 100755 index 0000000..8dea4eb --- /dev/null +++ b/expect/shell-pipelines/tr/script-01.sh @@ -0,0 +1,11 @@ +Dear Yara, + +Mz apologies for sending this response so late. As zou know, there's been a lot going on. + +Unfortunatelz I don't think I'll be able to make it to Yimbabwe, but but sounds amaying. + +Hope zou're doing well, and enjoz the trip. + +Thanks, + +Karolina diff --git a/expect/shell-pipelines/tr/script-02.sh b/expect/shell-pipelines/tr/script-02.sh new file mode 100755 index 0000000..e00561a --- /dev/null +++ b/expect/shell-pipelines/tr/script-02.sh @@ -0,0 +1,11 @@ +Dear Zara, + +My apologies for sending this response so late. As you know, there's been a lot going on! + +Unfortunately I don't think I'll be able to make it to Zimbabwe, but but sounds amazing! + +Hope you're doing well, and enjoy the trip! + +Thanks, + +Karolina diff --git a/individual-shell-tools/sed/script-01.sh b/individual-shell-tools/sed/script-01.sh index 3eba6fa..d592970 100755 --- a/individual-shell-tools/sed/script-01.sh +++ b/individual-shell-tools/sed/script-01.sh @@ -4,4 +4,4 @@ set -euo pipefail # TODO: Write a command to output input.txt with all occurrences of the letter `i` replaced with `I`. # The output should contain 11 lines. -# The first line of the output should be: "ThIs Is a sample fIle for experImentIng with sed.". +# The first line of the output should be: "ThIs Is a sample fIle for experImentIng wIth sed.". diff --git a/number-systems/Part-1.md b/number-systems/Part-1.md new file mode 100644 index 0000000..d8f9c29 --- /dev/null +++ b/number-systems/Part-1.md @@ -0,0 +1,54 @@ +Do not use any tools or programming to solve these problems. Work it out yourself by hand, and fill in the answers. + +Do not convert any binary numbers to decimal when solving a question unless the question explicitly tells you to. + +The goal of these exercises is for you to gain an intuition for binary numbers. Using tools to solve the problems defeats the point. + +The answers to these questions should be a number, either in binary, hex, or decimal. + +Q1: Convert the decimal number 14 to binary. +Answer: + +Q2: Convert the binary number 101101 to decimal: +Answer: + +Q3: Which is larger: 1000 or 0111? +Answer: + +Q4: Which is larger: 00100 or 01011? +Answer: + +Q5: What is 10101 + 01010? +Answer: + +Q6: What is 10001 + 10001? +Answer: + +Q7: What's the largest number you can store with 4 bits, if you want to be able to represent the number 0? +Answer: + +Q8: How many bits would you need in order to store the numbers between 0 and 255 inclusive? +Answer: + +Q9: How many bits would you need in order to store the numbers between 0 and 3 inclusive? +Answer: + +Q10: How many bits would you need in order to store the numbers between 0 and 1000 inclusive? +Answer: + +Q11: Convert the decimal number 14 to hex. +Answer: + +Q12: Convert the decimal number 386 to hex. +Answer: + +Q13: Convert the hex number 386 to decimal. +Answer: + +Q14: Convert the hex number B to decimal. +Answer: + +Q15: If reading the byte 0x21 as a number, what decimal number would it mean? +Answer: + +Q16: Continues in Part-2 diff --git a/number-systems/Part-2.md b/number-systems/Part-2.md new file mode 100644 index 0000000..92b7005 --- /dev/null +++ b/number-systems/Part-2.md @@ -0,0 +1,22 @@ +Do not use any tools or programming to solve these problems. Work it out yourself by hand, and fill in the answers. + +Do not convert any binary numbers to decimal when solving a question unless the question explicitly tells you to. + +The goal of these exercises is for you to gain an intuition for binary numbers. Using tools to solve the problems defeats the point. + +The answers to these questions will require a bit of explanation, not just a simple answer. + +Q16: How can you test if a binary number is a power of two (e.g. 1, 2, 4, 8, 16, ...)? +Answer: + +Q17: If reading the byte 0x21 as an ASCII character, what character would it mean? +Answer: + +Q18: If reading the byte 0x21 as a greyscale colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? +Answer: + +Q19: If reading the bytes 0xAA00FF as an RGB colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? +Answer: + +Q20: If reading the bytes 0xAA00FF as a sequence of three one-byte decimal numbers, what decimal numbers would they be? +Answer: diff --git a/number-systems/README.md b/number-systems/README.md deleted file mode 100644 index 77a3bde..0000000 --- a/number-systems/README.md +++ /dev/null @@ -1,65 +0,0 @@ -Do not use any tools or programming to solve these problems. Work it out yourself by hand, and fill in the answers. - -Do not convert any binary numbers to decimal when solving a question unless the question explicitly tells you to. - -The goal of these exercises is for you to gain an intuition for binary numbers. Using tools to solve the problems defeats the point. - -Convert the decimal number 14 to binary. -Answer: - -Convert the binary number 101101 to decimal: -Answer: - -Which is larger: 1000 or 0111? -Answer: - -Which is larger: 00100 or 01011? -Answer: - -What is 10101 + 01010? -Answer: - -What is 10001 + 10001? -Answer: - -What's the largest number you can store with 4 bits, if you want to be able to represent the number 0? -Answer: - -How many bits would you need in order to store the numbers between 0 and 255 inclusive? -Answer: - -How many bits would you need in order to store the numbers between 0 and 3 inclusive? -Answer: - -How many bits would you need in order to store the numbers between 0 and 1000 inclusive? -Answer: - -How can you test if a binary number is a power of two (e.g. 1, 2, 4, 8, 16, ...)? -Answer: - -Convert the decimal number 14 to hex. -Answer: - -Convert the decimal number 386 to hex. -Answer: - -Convert the hex number 386 to decimal. -Answer: - -Convert the hex number B to decimal. -Answer: - -If reading the byte 0x21 as a number, what decimal number would it mean? -Answer: - -If reading the byte 0x21 as an ASCII character, what character would it mean? -Answer: - -If reading the byte 0x21 as a greyscale colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? -Answer: - -If reading the bytes 0xAA00FF as an RGB colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? -Answer: - -If reading the bytes 0xAA00FF as a sequence of three one-byte decimal numbers, what decimal numbers would they be? -Answer: diff --git a/sprint-5-prep/1-use-types.py b/sprint-5-prep/1-use-types.py new file mode 100644 index 0000000..28d3014 --- /dev/null +++ b/sprint-5-prep/1-use-types.py @@ -0,0 +1,50 @@ +# Exercise-1 + +# Predict what double("22") will do. +# Then run the code and check. Did it do what you expected? +# Why did it return the value it did? + +def double(value): + return value * 2 + +#Answer +#I guess it'll return 2222. That's because any value in quotes is a string, +# and when strings are multiplied, they repeat the characters. + +def double(value): + return value * 2 + +print("double is:", double("22")) #double is: 2222 + +# Yes, It returned 2222 as I predicted. +# Python's operator "*" when used with a string and a number, repeats this string as "number" times, +# and it didn't convert the string "22" into number 22. + + +#Exercise-2 + +def double(number): + return number * 3 + +print(double(10)) + + +#Read the above code and write down what the bug is. How would you fix it? + +# Answer +# There are two way to fix it: +# 1. Change *3 to *2. + +def double(number): + return number * 2 + +print(double(10)) + +# or + +# 2. Rename the function to "triple" if we want multiply by 3 - it keeps the logic correct. + +def triple(number): + return number * 3 + +print(triple(10)) diff --git a/sprint-5-prep/2-type-checking-mypy.py b/sprint-5-prep/2-type-checking-mypy.py new file mode 100644 index 0000000..4d4cc1b --- /dev/null +++ b/sprint-5-prep/2-type-checking-mypy.py @@ -0,0 +1,31 @@ +from typing import Dict + +def open_account(balances: Dict[str, int], name: str, amount: int)-> None: + balances[name] = amount + +def sum_balances(accounts: Dict[str, int])-> int: + total = 0 + for name, pence in accounts.items(): + print(f"{name} had balance {pence}") + total += pence + return total + +def format_pence_as_string(total_pence: int)-> str: + if total_pence < 100: + return f"{total_pence}p" + pounds = int(total_pence / 100) + pence = total_pence % 100 + return f"£{pounds}.{pence:02d}" + +balances = { + "Sima": 700, + "Linn": 545, + "Georg": 831, +} + +open_account(balances, "Tobi", 913) +open_account(balances, "Olya", 713) + +total_pence = sum_balances(balances) + +print(f"The bank accounts total {total_string}") \ No newline at end of file diff --git a/sprint-5-prep/3-classes-and-objects.py b/sprint-5-prep/3-classes-and-objects.py new file mode 100644 index 0000000..2613ea1 --- /dev/null +++ b/sprint-5-prep/3-classes-and-objects.py @@ -0,0 +1,24 @@ +class Person: + def __init__(self, name: str, age: int, preferred_operating_system: str): + self.name = name + self.age = age + self.preferred_operating_system = preferred_operating_system + +imran = Person("Imran", 22, "Ubuntu") +print(imran.name) +#print(imran.address) +#error: Person class has no attribute "address" + +eliza = Person("Eliza", 34, "Arch Linux") +print(eliza.name) +#print(eliza.address) +#the same error: Person class has no attribute "address" + +def is_adult(person: Person) -> bool: + return person.age >= 18 + +print(is_adult(imran)) + +def get_phone(person: Person) -> str: + return person.phone_number +# After running mypy this method also causes an error, because Person class has no attribute "phone_number" \ No newline at end of file diff --git a/sprint-5-prep/4-methods.py b/sprint-5-prep/4-methods.py new file mode 100644 index 0000000..b442f30 --- /dev/null +++ b/sprint-5-prep/4-methods.py @@ -0,0 +1,44 @@ +# Exercises-1 +# Think of the advantages of using methods instead of free functions. +# Write them down in your notebook. + +# 1. Organisation: all Person-related logic lives inside the Person class. + +# 2. Encapsulation: we only have to update the method once, +# for example if we change "age" to "date_of_birth" inside the class. +# With free functions, we'd have to update every function that touches person.age across the whole codebase. + +# 3. Simple search: if we type "imran." our editor shows everything Person can do. +# With free functions, we have to remember they exist. + +# 4. Clear ownership: "person.is_adult()" is definitely about a person, +# but with "is_adult(x)" we don't know what it's about. + +# 5. Easier to catch errors with mypy, because all methods related to the class are in one place. + + +# Exercises-2 +# Change the Person class to take a date of birth (using the standard library’s datetime.date class) +# and store it in a field instead of age. +# +# Update the is_adult method to act the same as before. + +from datetime import date + +class Person: + def __init__(self, name: str, date_of_birth: date, preferred_operating_system: str): + self.name = name + self.date_of_birth = date_of_birth + self.preferred_operating_system = preferred_operating_system + + def is_adult(self) -> bool: + today = date.today() + age = today.year - self.date_of_birth.year + + if(today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): + age -= 1 + + return age >= 18 + +imran = Person("Imran", date(2003, 6, 20), "Ubuntu") +print(imran.is_adult()) diff --git a/sprint-5-prep/5-dataclasses.py b/sprint-5-prep/5-dataclasses.py new file mode 100644 index 0000000..9ebbb12 --- /dev/null +++ b/sprint-5-prep/5-dataclasses.py @@ -0,0 +1,22 @@ +from dataclasses import dataclass +from datetime import date + +@dataclass(frozen=True) +class Person: + name: str + date_of_birth: date + preferred_operating_system: str + + def is_adult(self) -> bool: + today = date.today() + + age = today.year - self.date_of_birth.year + if (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day): + age -= 1 + return age >= 18 + + +zoi = Person("Zoi", date(2003, 3, 23), "Ubuntu") + +print("zoi:", zoi) +print("zoi.is_adult():", zoi.is_adult()) \ No newline at end of file diff --git a/sprint-5-prep/6-generics.py b/sprint-5-prep/6-generics.py new file mode 100644 index 0000000..8bbece5 --- /dev/null +++ b/sprint-5-prep/6-generics.py @@ -0,0 +1,20 @@ +from dataclasses import dataclass +from typing import List + +@dataclass(frozen=True) +class Person: + name: str + children: list["Person"] + age: int + +fatma = Person(name="Fatma", age=9, children=[]) +aisha = Person(name="Aisha", age=5, children=[]) + +imran = Person(name="Imran", age=35, children=[fatma, aisha]) + +def print_family_tree(person: Person) -> None: + print(person.name) + for child in person.children: + print(f"- {child.name} ({child.age})") + +print_family_tree(imran) \ No newline at end of file diff --git a/sprint-5-prep/7-type-guided-refactorings.py b/sprint-5-prep/7-type-guided-refactorings.py new file mode 100644 index 0000000..1d098e4 --- /dev/null +++ b/sprint-5-prep/7-type-guided-refactorings.py @@ -0,0 +1,42 @@ +from dataclasses import dataclass +from typing import List + +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_systems: List[str] + + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: str + + +def find_possible_laptops(laptops: List[Laptop], person: Person) -> List[Laptop]: + possible_laptops = [] + for laptop in laptops: + if laptop.operating_system in person.preferred_operating_systems: + possible_laptops.append(laptop) + return possible_laptops + + +people = [ + Person(name="Imran", age=22, preferred_operating_systems=["Ubuntu"]), + Person(name="Eliza", age=34, preferred_operating_systems=["Arch Linux"]), +] + +laptops = [ + Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system="Arch Linux"), + Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="Ubuntu"), + Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system="ubuntu"), + Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system="macOS"), +] + +for person in people: + possible_laptops = find_possible_laptops(laptops, person) + print(f"Possible laptops for {person.name}: {possible_laptops}") \ No newline at end of file diff --git a/sprint-5-prep/8-enums.py b/sprint-5-prep/8-enums.py new file mode 100644 index 0000000..7b666ef --- /dev/null +++ b/sprint-5-prep/8-enums.py @@ -0,0 +1,79 @@ +from dataclasses import dataclass +from enum import Enum +from typing import List +import sys + +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: OperatingSystem + +@dataclass(frozen=True) +class Laptop: + id: int + manufacturer: str + model: str + screen_size_in_inches: float + operating_system: OperatingSystem + +os_input_name = input("Your name is: ") + +os_input_age = input("Your age is: ") +try: + age = int(os_input_age) +except ValueError: + print(f"Error: '{os_input_age}' is not a valid age", file=sys.stderr) + sys.exit(1) + +os_input_preferred_os = input("Preferred operating system is: ") +try: + preferred_operating_system = OperatingSystem(os_input_preferred_os) +except ValueError: + print(f"Error: '{os_input_preferred_os}' is not a valid operating system", file=sys.stderr) + sys.exit(1) + +person = Person(name = os_input_name, age=age, preferred_operating_system=preferred_operating_system) + +laptops = [ + Laptop(id=1, manufacturer="Dell", model="XPS", screen_size_in_inches=13, operating_system=OperatingSystem.ARCH), + Laptop(id=2, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), + Laptop(id=3, manufacturer="Dell", model="XPS", screen_size_in_inches=15, operating_system=OperatingSystem.UBUNTU), + Laptop(id=4, manufacturer="Apple", model="macBook", screen_size_in_inches=13, operating_system=OperatingSystem.MACOS), + Laptop(id=5, manufacturer="Apple", model="macBook", screen_size_in_inches=14, operating_system=OperatingSystem.MACOS), + Laptop(id=6, manufacturer="Apple", model="macBook", screen_size_in_inches=15, operating_system=OperatingSystem.MACOS), +] + +def find_specific_os(laptops: List[Laptop], preferred_os: OperatingSystem) -> List[Laptop]: + possible_laptops = [] + + for laptop in laptops: + if (laptop.operating_system == preferred_os): + possible_laptops.append(laptop) + + possible_laptops_amount = len(possible_laptops) + + print(f"The amount of possible laptops with preferred operating system is", possible_laptops_amount) + + return possible_laptops + +result = find_specific_os(laptops, preferred_operating_system) + +counts_laptop_per_os: dict[OperatingSystem, int] = {} + +for laptop in laptops: + os = laptop.operating_system + if os in counts_laptop_per_os: + counts_laptop_per_os[os] += 1 + else: + counts_laptop_per_os[os] = 1 + +top_os = max(counts_laptop_per_os, key=lambda os: counts_laptop_per_os[os]) + +if top_os != preferred_operating_system: + print(f"If you're willing to use {top_os.value}, you're more likely to get a laptop ({counts_laptop_per_os[top_os]} available)") \ No newline at end of file diff --git a/sprint-5-prep/9-inheritance.py b/sprint-5-prep/9-inheritance.py new file mode 100644 index 0000000..af08fd1 --- /dev/null +++ b/sprint-5-prep/9-inheritance.py @@ -0,0 +1,67 @@ +class Parent: + def __init__(self, first_name: str, last_name: str): + self.first_name = first_name + self.last_name = last_name + + def get_name(self) -> str: + return f"{self.first_name} {self.last_name}" + + +class Child(Parent): + def __init__(self, first_name: str, last_name: str): + super().__init__(first_name, last_name) + self.previous_last_names = [] + + def change_last_name(self, last_name) -> None: + self.previous_last_names.append(self.last_name) + self.last_name = last_name + + def get_full_name(self) -> str: + suffix = "" + if len(self.previous_last_names) > 0: + suffix = f" (née {self.previous_last_names[0]})" + return f"{self.first_name} {self.last_name}{suffix}" + + +# --- Predictions --- + +person1 = Child("Elizaveta", "Alekseeva") + +print(person1.get_name()) +# Prediction: "Elizaveta Alekseeva" +# Reason: Child inherits get_name() from Parent, no name change yet + +print(person1.get_full_name()) +# Prediction: "Elizaveta Alekseeva" +# Reason: no previous last names, so suffix is empty string + +person1.change_last_name("Tyurina") +# Saves "Alekseeva" into previous_last_names list, changes last_name to "Tyurina" + +print(person1.get_name()) +# Prediction: "Elizaveta Tyurina" +# Reason: get_name() uses self.last_name which is now "Tyurina" + +print(person1.get_full_name()) +# Prediction: "Elizaveta Tyurina (nee Alekseeva)" +# Reason: previous_last_names is not empty, so suffix shows the original last name + +person2 = Parent("Elizaveta", "Alekseeva") + +print(person2.get_name()) +# Prediction: "Elizaveta Alekseeva" +# Reason: Parent has get_name(), works normally + +# print(person2.get_full_name()) +# Prediction: ERROR - AttributeError +# Reason: Parent class does not have get_full_name() method, only Child does + +# person2.change_last_name("Tyurina") +# Prediction: ERROR - AttributeError +# Reason: Parent class does not have change_last_name() method, only Child does + +# print(person2.get_name()) +# Would print "Elizaveta Alekseeva" but we can't reach this line because of the error above + +# print(person2.get_full_name()) +# Would also error - Parent still doesn't have get_full_name() \ No newline at end of file diff --git a/test-sdc.sh b/test-sdc.sh new file mode 100755 index 0000000..62d1c7e --- /dev/null +++ b/test-sdc.sh @@ -0,0 +1,182 @@ +#!/bin/bash + +# This test file will be automatically run when you submit a pull request +# You should not modify this file +# You can run this file using ./test-sdc.sh task-directory-name to check your output + +echo "" > testoutput.txt +echo "Results of test:" >> testoutput.txt + +if [[ "$1" == "individual-shell-tools" ]]; then + cd individual-shell-tools + pass=0 + total=0 + for directory in */; do + cd $directory + if [ "$directory" == "helper-files/" ]; then + cd .. + continue + fi + for exercise in *.sh; do + total=$(($total+1)) + ./$exercise > ../../test.tmp + cmp ../../test.tmp ../../expect/individual-shell-tools/$directory$exercise + if [ $? -eq 0 ]; then + pass=$(($pass+1)) + else + if [[ "$exercise" == *"stretch"* && $(stat -c%s ../../test.tmp) == "0" ]]; then + # Stretch task not attempted, ignoring" + total=$(($total-1)) + else + echo "Failed $directory$exercise, please check" >> ../../testoutput.txt + fi + fi + done + cd .. + done + cd .. + rm test.tmp + echo "You passed $pass/$total tasks." >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "attempted=y" >> "$GITHUB_OUTPUT" + fi + if [ $pass -ge $total ]; then + echo "This task is complete!" >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "complete=y" >> "$GITHUB_OUTPUT" + fi + fi + cat testoutput.txt +elif [[ "$1" == "shell-pipelines" ]]; then + cd shell-pipelines + pass=0 + total=0 + for directory in */; do + cd $directory + for exercise in *.sh; do + total=$(($total+1)) + ./$exercise > ../../test.tmp + cmp ../../test.tmp ../../expect/shell-pipelines/$directory$exercise + if [ $? -eq 0 ]; then + pass=$(($pass+1)) + else + echo "Failed $directory$exercise, please check" >> ../../testoutput.txt + fi + done + cd .. + done + cd .. + rm test.tmp + echo "You passed $pass/$total tasks." >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "attempted=y" >> "$GITHUB_OUTPUT" + fi + if [ $pass -eq $total ]; then + echo "This task is complete!" >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "complete=y" >> "$GITHUB_OUTPUT" + fi + fi + cat testoutput.txt +elif [[ "$1" == "jq" ]]; then + cd jq + pass=0 + total=0 + for exercise in *.sh; do + total=$(($total+1)) + ./$exercise > ../test.tmp + cmp ../test.tmp ../expect/jq/$exercise + if [ $? -eq 0 ]; then + pass=$(($pass+1)) + else + echo "Failed $exercise, please check" >> ../testoutput.txt + fi + done + cd .. + rm test.tmp + echo "You passed $pass/$total tasks." >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "attempted=y" >> "$GITHUB_OUTPUT" + fi + if [ $pass -eq $total ]; then + echo "This task is complete!" >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "complete=y" >> "$GITHUB_OUTPUT" + fi + fi + cat testoutput.txt +elif [[ "$1" == "number-systems" ]]; then + pass=0 + for question in $(seq 1 15); do + answer=$(jq -r ".answers[$question]" expect/number-systems/Part-1.json) + nextq=$(($question+1)) + Q_START=$(grep -n "Q$question:" number-systems/Part-1.md | cut -d: -f1) + ANS_START=$(($Q_START + 1)) + NEXT_Q_START=$(grep -n "Q$nextq:" number-systems/Part-1.md | cut -d: -f1) + ANS_END=$(($NEXT_Q_START - 1)) + sed -n "$ANS_START,${ANS_END}p;${NEXT_Q_START}q" number-systems/Part-1.md | cut -d: -f2- > answerfile + grep --quiet -iE $answer answerfile + if [ $? -eq 0 ]; then + pass=$(($pass+1)) + else + echo "Q$question incorrect, please check" >> testoutput.txt + fi + rm answerfile + done + echo "You passed $pass/15 tasks in part 1." >> testoutput.txt + if [ -v GITHUB_OUTPUT ]; then + echo "attempted=y" >> "$GITHUB_OUTPUT" + fi + echo "Please let a volunteer check the answers for part 2." >> testoutput.txt + cat testoutput.txt +elif [[ "$1" == "implement-cowsay" ]]; then + if [ -v GITHUB_OUTPUT ]; then + echo "attempted=y" >> "$GITHUB_OUTPUT" + fi + if [[ -e .cowsay-venv ]]; then + echo ".cowsay-venv already exists - couldn't test cowsay" >> testoutput.txt + else + if [ ! -e implement-cowsay/requirements.txt ]; then + echo "Expected implement-cowsay/requirements.txt to exist but it didn't" >> testoutput.txt + else + python3 -m venv .cowsay-venv + . .cowsay-venv/bin/activate + pip3 install -r implement-cowsay/requirements.txt + + all_ok=true + + python3 implement-cowsay/cow.py Grass, delicious > test.tmp + cmp test.tmp expect/implement-cowsay/cow-grass.txt + if [ $? -ne 0 ]; then + echo "Unexpected cowsay output for 'Grass, delicious'." >> testoutput.txt + all_ok=false + fi + + python3 implement-cowsay/cow.py --animal turtle "Fish are cool!" > test.tmp + cmp test.tmp expect/implement-cowsay/turtle-fish.txt + if [ $? -ne 0 ]; then + echo "Unexpected cowsay output for --animal turtle Fish are cool!" >> testoutput.txt + all_ok=false + fi + + python3 implement-cowsay/cow.py --help | grep dragon + if [ $? -ne 0 ]; then + echo "Expected python3 cow.py --help to include dragon as it's one of the animal options" >> testoutput.txt + all_ok=false + fi + + grep dragon implement-cowsay/cow.py > /dev/null + if [ $? -eq 0 ]; then + echo "Didn't expect cow.py to include the word dragon - you should pull in the animal options from the library not write them yourself" >> testoutput.txt + all_ok=false + fi + + if [[ "${all_ok}" == "true" && -v GITHUB_OUTPUT ]]; then + echo "complete=y" >> "$GITHUB_OUTPUT" + echo "Your implementation passed all checks." >> testoutput.txt + fi + fi + fi +else + echo "Please run this with a valid test directory name as argument" +fi