0

Having in mind that there are seven notes of music and seven letters are often used to represent them:

Note    Symbol
Do       c
Re       d
Mi       e
Fa       f
Sol      g
La       a
Si       b

Here are 7 possible octaves in total:

"c1": Do of the 1st octave,
"d1": Re of the 1st octave,
"g1": Sol of the 1st octave,
"c2": Do of the 2nd octave,
"a5": Mi of the 5th octave.

I have a predefined function get_note() that returns a note in the specified format.

There is a need to write a decorator with an integer parameter that denotes how to change the input note, meaning:

 0 : do not change at all,
 1 : one octave up,
-3 : three octaves down,
etc.

This is how the call looks like:

from random import choice


    @transpose(2)  # parameter 
    def get_note():
        note = choice(['c', 'd', 'e', 'f', 'g', 'a', 'h'])
        octave = choice(range(1, 8))
        print(f"Initial: {note}{octave}")
        return f"{note}{octave}"
    
    
    returned = get_note()
    print(f"result: {returned}")

Also, It is not allowed to move the note below the 1st octave and above the 7th octave.

Example1:

input
d4 
-3
output
d1

Example2:

input
c7
2
output
c7

Here how transpose decorator is defined and it is not quite right.

def transpose(*args):
    def wrapper(func):
        print(*args)
        note, octave = func()
        octave = int(octave)
        print(octave)
        octave += int(*args)
        print(octave)
        return f"{note}{octave}"

    return wrapper

@transpose
def get_note():
    ...  # function chooses the note
    return f"{note}{octave}" 

I need you to help me find out what should I correct in my transpose decorator.

furas
  • 134,197
  • 12
  • 106
  • 148
  • 1
    Is the question how to write the `transpose` decorator so that it can accept an argument, like in the first example code? – Anentropic Oct 19 '22 at 09:40
  • 4
    This is not a good usecase for decorators. `transpose` should be a parameter for `get_note()`, as it sounds like that's a value that might change between different calls of the function. – matszwecja Oct 19 '22 at 09:40
  • @Anentropic yes, I need to give inputs like d4 and -3 and have output d1 for example – Albina Hakobyan Oct 19 '22 at 09:42
  • I agree with what @matszwecja is saying - you don't need decorators - you are only modifying the output from `get_note`, which means you can pass the output of `get_note()` to a `transpose` function. – Mortz Oct 19 '22 at 09:49
  • As I remember decorator with parameters may need another nested function. Something like `def transpose: def arguments: def wrapper` instead of `def transpose: def wrapper` – furas Oct 19 '22 at 10:11
  • decorator with arguments: https://stackoverflow.com/a/5929165/202168 – Anentropic Oct 19 '22 at 11:42

0 Answers0