-1

For a task I have to write a function that prints the number of numbers that are factors of 12 when provided with a sequence of numbers. My problem now is that my function keeps printing 0. What am I doing wrong?

Below is my code:

#!/usr/bin/bash
#File: Num_Factor
#Write a function which prints factors of the first argument

function num_factor {
  local sum=0
  for element in $@; do
    let factorcheck=$(( element % 2 ))
    if [[ $factorcheck -eq 0 ]]; then
      let sum=sum+1
    fi
  done
  echo $sum
}

num_factor

The expected output am trying to achieve should be something similar to this:

$num_factor 12 4 6 1 5
4

Thanks.

  • 4
    In `factorcheck=$(( element % 2 ))` - dividing 4 or 5 by 2 and checking the remainder wouldn't tell you if either of them is a factor of 12, it just tells you if it's an even or odd number (i.e. if 2 is a factor of them). Also, run your code through http://shellcheck.net and fix the issues it tells you about. – Ed Morton Jul 26 '22 at 22:04
  • 3
    Change `element % 2` to `12 % element` – Barmar Jul 26 '22 at 22:17
  • 2
    When you run the `num_factor` function, you don't pass it any arguments, so `$@` will be empty inside it. You probably want to pass on the script's arguments with `num_factor "$@"`. See ["How to pass all arguments passed to my bash script to a function of mine?"](https://stackoverflow.com/questions/3811345/how-to-pass-all-arguments-passed-to-my-bash-script-to-a-function-of-mine) (Note: [shellcheck.net](https://www.shellcheck.net) will spot this and many other common mistakes; strongly recommended!) – Gordon Davisson Jul 26 '22 at 23:25
  • nowhere in the code is the 1st parameter being captured so that it can be used in all of the follow-on comparisons; does the expected output show `4` because you consider `12` as a factor of `12` (ie, you always compare the 1st parameter against itself)? – markp-fuso Jul 27 '22 at 00:52
  • `$@` refers to the arguments of your function `num_factor`, but you don't pass any argument to your function. Therefore the loop is skipped. You can find this kind of errors easily by putting a `set -x` before calling the function. – user1934428 Jul 27 '22 at 06:41

1 Answers1

0

Assumptions:

  • the first parameter is to be compared against itself
  • all parameters are guaranteed to be integers otherwise will need to use something else (bc? awk?)

Making a few tweaks to OP's current code:

num_factor() {
  local sum=0 first=$1                                    # initialize counter, grab first parameter
  # shift                                                 # uncomment this line if the first parameter is *NOT* to be compared with itself
  for element in "$@"; do
    [[ "$element"           -eq 0 ]] && continue          # skip 'divide by 0' scenario
    [[ $((first % element)) -eq 0 ]] && let sum=sum+1
  done
  echo $sum
}

Taking it for a test drive:

$ num_factor 12 4 6 1 5
4

$ num_factor 13
1

$ num_factor 13 2 3 5 7 9 11
1

$ num_factor -12 2 6 -3 5 1
5

$ num_factor 0 1 2 3 4 5 6
6                                   # based on OP's current logic; OP may want to reconsider how to address when 1st parameter == `0`

$ num_factor 720 2 3 4 5 6
6
markp-fuso
  • 28,790
  • 4
  • 16
  • 36
  • I am still running into an error...The output am getting is 0 for some reason that am not understanding :( – Giddyspurz Jul 27 '22 at 05:44
  • please provide an example of how you're calling the function; if all you're doing is `num_factor` (without any parameters) then, yeah, it will return `0` since you don't provide any parameters to `num_factor`; I've provided 6x examples of calling `num_factor` with parameters ... are you saying that each time you run one of those examples you are getting `0` as a result? – markp-fuso Jul 27 '22 at 12:54