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..c4234ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +testoutput.txt 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/implement-shell-tools/ls/README.md b/implement-shell-tools/ls/README.md index edbfb81..c0b81e0 100644 --- a/implement-shell-tools/ls/README.md +++ b/implement-shell-tools/ls/README.md @@ -6,6 +6,9 @@ Your task is to implement your own version of `ls`. It must act the same as `ls` would, if run from the directory containing this README.md file, for the following command lines: +* `ls sample-files` +* `ls sample-files/1.txt` +* `ls sample-files/*` * `ls -1` * `ls -1 sample-files` * `ls -1 -a sample-files` diff --git a/implement-shell-tools/wc/README.md b/implement-shell-tools/wc/README.md index bd76b65..925e522 100644 --- a/implement-shell-tools/wc/README.md +++ b/implement-shell-tools/wc/README.md @@ -11,6 +11,8 @@ It must act the same as `wc` would, if run from the directory containing this RE * `wc -w sample-files/3.txt` * `wc -c sample-files/3.txt` * `wc -l sample-files/*` +* `wc -w -l sample-files/3.txt` +* `wc -w -l sample-files/*` Matching any additional behaviours or flags are optional stretch goals. 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..68b0933 --- /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 a sequence of three one-byte decimal numbers, what decimal numbers would they be? +Answer: + +Q20: If reading the bytes 0xAA00FF as an RGB colour, as described in "Approaches for Representing Colors and Images", what colour would it mean? +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-exercises/.gitignore b/sprint-5-prep-exercises/.gitignore new file mode 100644 index 0000000..1d17dae --- /dev/null +++ b/sprint-5-prep-exercises/.gitignore @@ -0,0 +1 @@ +.venv diff --git a/sprint-5-prep-exercises/exercise_01.py b/sprint-5-prep-exercises/exercise_01.py new file mode 100644 index 0000000..7b42748 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_01.py @@ -0,0 +1,12 @@ +# Exercise +# Predict what double("22") will do. +# It will treat "22" as a integer and return 11 as an integer + +# Then run the code and check. +def double(value): + return value * 2 + +print(double("22")) + +# Did it do what you expected? Why did it return the value it did? +# No, it treated it like a string, so instead of trying to do math, it did string repetition. \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_02.py b/sprint-5-prep-exercises/exercise_02.py new file mode 100644 index 0000000..e494911 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_02.py @@ -0,0 +1,10 @@ +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? + +# Potential bug: Code says double and it is multiplying by 3 + +# It could be fixed by changing the name of the function to triple, or the integer to 2. \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_03.py b/sprint-5-prep-exercises/exercise_03.py new file mode 100644 index 0000000..76e29a4 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_03.py @@ -0,0 +1,30 @@ +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) +total_string = format_pence_as_string(total_pence) + +print(f"The bank accounts total {total_string}") \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_04_and_05.py b/sprint-5-prep-exercises/exercise_04_and_05.py new file mode 100644 index 0000000..adcd072 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_04_and_05.py @@ -0,0 +1,35 @@ +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) + +eliza = Person("Eliza", 34, "Arch Linux") +print(eliza.name) +print(eliza.address) + +# exercise_4_and_5.py:9: error: "Person" has no attribute "address" [attr-defined] +# exercise_4_and_5.py:13: error: "Person" has no attribute "address" [attr-defined] +# Found 2 errors in 1 file (checked 1 source file) + +# There is no address attribute for a Person, only name, age and preferred operating system. + +# Add the is_adult code to the file you saved earlier. +def is_adult(person: Person) -> bool: + return person.age >= 18 + +print(is_adult(imran)) + +# Run it through mypy - notice that no errors are reported - +# mypy understands that Person has a property named age so is happy with the function. + +def is_banana(person: Person) -> bool: + return person.banana + +print(is_banana(imran)) + +# exercise_4_and_5.py:31: error: "Person" has no attribute "banana" [attr-defined] \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_06.py b/sprint-5-prep-exercises/exercise_06.py new file mode 100644 index 0000000..04b348e --- /dev/null +++ b/sprint-5-prep-exercises/exercise_06.py @@ -0,0 +1,13 @@ +# Think of the advantages of using methods instead of free functions. Write them down in your notebook. + +# Better readability of code +# - Method names can be simplified as they only apply to that class, they are contained within the class which is more +# organised and method names can be reused in different classes. + +# Encapsulation of that function only to class - cleaner and better security. +# - This can allow for discoverability of methods when writing code using . in an IDE. +# - Data can be protected from outside functions changing it, this allows for control over what can be changed using +# only the inbuilt methods of a class + +# Potential drawback: For a function that may want to be used on class objects from multiple different classes it may +# be better to use a function instead of repeated a method for each class. diff --git a/sprint-5-prep-exercises/exercise_07.py b/sprint-5-prep-exercises/exercise_07.py new file mode 100644 index 0000000..dfe3d3a --- /dev/null +++ b/sprint-5-prep-exercises/exercise_07.py @@ -0,0 +1,25 @@ +from datetime import date + + +class Person: + def __init__(self, name: str, dob: date, preferred_operating_system: str): + self.name = name + self.dob = dob + self.preferred_operating_system = preferred_operating_system + + def is_adult(self): + dob = self.dob + today = date.today() + today_tuple = (today.year, today.month, today.day) + eighteenth_bday_tuple = (dob.year + 18, dob.month, dob.day) + + return today_tuple >= eighteenth_bday_tuple + + +imran = Person("Imran", date(2004, 8, 31), "Ubuntu") +print(imran.is_adult()) + +# 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. diff --git a/sprint-5-prep-exercises/exercise_08.py b/sprint-5-prep-exercises/exercise_08.py new file mode 100644 index 0000000..8b1ef95 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_08.py @@ -0,0 +1,24 @@ +# Write a Person class using @datatype which uses a datetime.date for date of birth, rather than an int for age. +from dataclasses import dataclass +from datetime import date + +@dataclass(frozen=True) +class Person: + name: str + dob: date + preferred_operating_system: str + +# Re-add the is_adult method to it. + def is_adult(self): + dob = self.dob + today = date.today() + if dob.year > today.year - 18: return False + if dob.year == today.year - 18: + if dob.month > today.month: return False + if dob.month == today.month: + if dob.day > today.day: return False + return True + + +imran = Person("Imran", date(2004, 8, 31), "Ubuntu") +print(imran.is_adult()) \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_09.py b/sprint-5-prep-exercises/exercise_09.py new file mode 100644 index 0000000..c406bf6 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_09.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass +from typing import List + +@dataclass(frozen=True) +class Person: + name: str + children: List["Person"] + age: int + +fatma = Person(name="Fatma", children=[], age=82) +aisha = Person(name="Aisha", children=[], age=83) + +imran = Person(name="Imran", children=[fatma, aisha], age=102) + +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) + +# Fix the above code so that it works. +# You must not change the print on line 17 - we do want to print the children’s ages. +# (Feel free to invent the ages of Imran’s children.) \ No newline at end of file diff --git a/sprint-5-prep-exercises/exercise_10.py b/sprint-5-prep-exercises/exercise_10.py new file mode 100644 index 0000000..43eca83 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_10.py @@ -0,0 +1,83 @@ +from dataclasses import dataclass + + +@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}") + +# Try changing the type annotation of Person.preferred_operating_system from str to List[str]. +# Run mypy on the code. + +# exercise_10.py:29: error: Argument "preferred_operating_system" to "Person" has incompatible type "str"; expected "list[str]" [arg-type] +# exercise_10.py:30: error: Argument "preferred_operating_system" to "Person" has incompatible type "str"; expected "list[str]" [arg-type] + + +# It tells us different places that our code is now wrong, because we’re passing values of the wrong type. +# We probably also want to rename our field - lists are plural. Rename the field to preferred_operating_systems. +# Run mypy again. + +# exercise_10.py:23: error: "Person" has no attribute "preferred_operating_system"; maybe "preferred_operating_systems"? [attr-defined] +# exercise_10.py:29: error: Unexpected keyword argument "preferred_operating_system" for "Person"; did you mean "preferred_operating_systems"? [call-arg] +# exercise_10.py:30: error: Unexpected keyword argument "preferred_operating_system" for "Person"; did you mean "preferred_operating_systems"? [call-arg] + +# Fix all of the places that mypy tells you need changing. Make sure the program works as you’d expect. diff --git a/sprint-5-prep-exercises/exercise_11.py b/sprint-5-prep-exercises/exercise_11.py new file mode 100644 index 0000000..69b48db --- /dev/null +++ b/sprint-5-prep-exercises/exercise_11.py @@ -0,0 +1,101 @@ +# Write a program which: + +# Already has a list of Laptops that a library has to lend out. +# Accepts user input to create a new Person - it should use the input function to read a person’s name, age, and preferred operating system. +# Tells the user how many laptops the library has that have that operating system. +# If there is an operating system that has more laptops available, tells the user that if they’re willing to accept that operating system they’re more likely to get a laptop. + +# You should convert the age and preferred operating system input from the user into more constrained types as quickly as possible, +# and should output errors to stderr and terminate the program with a non-zero exit code if the user input bad values. + +# ----- Imports +import sys +from dataclasses import dataclass +from enum import Enum + + +# ----- Classes and Enums +class OperatingSystem(Enum): + MACOS = "macOS" + ARCH = "Arch Linux" + UBUNTU = "Ubuntu" + WINDOWS = "Windows" + + +@dataclass(frozen=True) +class Person: + name: str + age: int + preferred_operating_system: OperatingSystem + + +@dataclass(frozen=True) +class Laptop: + id: int + operating_system: OperatingSystem + + +# ----- Functions +def count_laptops(laptops: list[Laptop], laptop_counts: dict[str, int]): + for laptop in laptops: + laptop_counts[laptop.operating_system] += 1 + + +def check_laptop_abundance(user: Person, laptop_counts: dict[OperatingSystem, int]): + abundant_laptops = [] + for laptop in laptop_counts: + if laptop_counts[laptop] > laptop_counts[user.preferred_operating_system]: + abundant_laptops.append(laptop.value) + if len(abundant_laptops) > 0: + print( + "\nIf you are willing to accept another operating system you may get a laptop sooner." + ) + print("We have more laptops available with the following OS:") + for laptop in abundant_laptops: + print(laptop) + + +# ----- Data and Constants +laptops = [ + Laptop(id=1, operating_system=OperatingSystem.ARCH), + Laptop(id=2, operating_system=OperatingSystem.ARCH), + Laptop(id=3, operating_system=OperatingSystem.UBUNTU), + Laptop(id=4, operating_system=OperatingSystem.UBUNTU), + Laptop(id=5, operating_system=OperatingSystem.UBUNTU), + Laptop(id=6, operating_system=OperatingSystem.UBUNTU), + Laptop(id=7, operating_system=OperatingSystem.MACOS), + Laptop(id=8, operating_system=OperatingSystem.MACOS), +] +laptop_counts = { + OperatingSystem.MACOS: 0, + OperatingSystem.ARCH: 0, + OperatingSystem.UBUNTU: 0, + OperatingSystem.WINDOWS: 0, +} + +# ----- Script +user_name = input("Please enter your full name:\n") +user_age_str = input("Please enter your age:\n") + +try: + user_age = int(user_age_str) +except ValueError: + sys.exit("Error: Age should be a number.") + +user_operating_system_str = input( + "Please enter your preferred operating system (options: Arch, Ubuntu, MacOS, Windows):\n" +).upper() + +if user_operating_system_str not in OperatingSystem.__members__: + sys.exit("Error: Please enter a valid operating system from the given options.") +else: + user_operating_system = OperatingSystem[user_operating_system_str] + +user = Person(user_name, user_age, user_operating_system) + +count_laptops(laptops, laptop_counts) +print( + f"\nThe number of available laptops with {user_operating_system.value} is: {laptop_counts[user_operating_system]}" +) + +check_laptop_abundance(user, laptop_counts) diff --git a/sprint-5-prep-exercises/exercise_12.py b/sprint-5-prep-exercises/exercise_12.py new file mode 100644 index 0000000..8ab0c34 --- /dev/null +++ b/sprint-5-prep-exercises/exercise_12.py @@ -0,0 +1,81 @@ +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}" + +person1 = Child("Elizaveta", "Alekseeva") +# Prediction: Creates instance of Child class with first name "Elizaveta" and last name "Alekseeva". +print(person1) +print(person1.first_name) +print(person1.last_name) +# Outcome: As expected. + + +print(person1.get_name()) +# Prediction: Child inherits Parent methods, therefore calls get_name method: "Elizaveta Alekseeva" +# Outcome: As expected. + +print(person1.get_full_name()) +# Prediction: Calls get_full_name on child, no previous names: "Elizaveta Alekseeva" +# Outcome: As expected. + +person1.change_last_name("Tyurina") +# Prediction: Changes last_name to "Tyurina", and previous_last_names to ["Alekseeva"], returns nothing +print(person1.last_name) +print(person1.previous_last_names) +# Outcome: As expected. + +print(person1.get_name()) +# Prediction: Child inherits Parent methods, therefore calls get_name method: "Elizaveta Alekseeva" +# Outcome: As expected. + +print(person1.get_full_name()) +# Prediction: Returns first_name last_name (née previous_last_names[0]) (original last name) +# ""Elizaveta Tyurina (née Alekseeva)" +# Outcome: As expected. + +person2 = Parent("Elizaveta", "Alekseeva") +# Prediction: Creates instance of Parent class with first name "Elizaveta" and last name "Alekseeva". +print(person2) +print(person2.first_name) +print(person2.last_name) +# Outcome: As expected. + +print(person2.get_name()) +# Prediction: Calls get_name method: "Elizaveta Alekseeva" +# Outcome: As expected. + +# print(person2.get_full_name()) +# Prediction: Parent instance has not access to Child methods, will error that there is no method of get_full_name. +# Outcome: AttributeError: 'Parent' object has no attribute 'get_full_name' + +# person2.change_last_name("Tyurina") +# Prediction: Parent instance has not access to Child methods, will error that there is no method of change_last_name. +# Outcome: AttributeError: 'Parent' object has no attribute 'change_last_name' + +print(person2.get_name()) +# Prediction: Calls get_name method: "Elizaveta Alekseeva" as name has not changed due to inability to call change_last_name +# Outcome: As expected. + +# print(person2.get_full_name()) +# Prediction: Parent instance has not access to Child methods, will error that there is no method of get_full_name. +# Outcome: AttributeError: 'Parent' object has no attribute '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