0

I'm trying to create a very simple guitar tab creator in python, I had the idea but i'm not sure how to execute it the way I want. For example, I have a list containing each guitar string as a different item in the list, and I want the the user to be able to input which fret they want to use and which note. How can I replace a specific char in a list item based on a index number.

This is what I have so far:

tab = ['E|------------', 'B|------------', 'G|------------', 'D|------------', 'A|------------', 'E|------------']

for line in tab:
    print(line)

fret = input("Fret: ")
note = input("Note: ")

#if note == 'E':
   (Stuck here)

The output I'm looking for is something like:

e|-------5-7-----7-|-8-----8-2-----2-|-0---------0-----|-----------------|
B|-----5-----5-----|---5-------3-----|---1---1-----1---|-0-1-1-----------|
G|---5---------5---|-----5-------2---|-----2---------2-|-0-2-2---2-------|
D|-7-------6-------|-5-------4-------|-3---------------|-----------------|
A|-----------------|-----------------|-----------------|-2-0-0---0--/8-7-|
E|-----------------|-----------------|-----------------|-----------------|

I am aware that there is much more needed to get the output i'm looking for, but I want to try to figure that stuff out by myself first, I'm just looking for a nudge in the right direction to get a list item changed.

2
  • 1
    Python strings don't support item assignment through indexing, so it might be inconvenient to have each string as an actual string instead of a list of characters. You could convert them to lists and use indexing to replace a character through assignment, so directly from your example: tmp = list(tab[0])[fret]=note, convert it back to a string with new_string = "".join(tmp) Commented Jun 24, 2022 at 16:03
  • What about building a fret, like fret = "D|"+("-"*1)+"7"+("-"*7)+"6"+("-"*7)? Commented Jun 24, 2022 at 16:05

1 Answer 1

2

Note sure how you want to construct the whole thing, but here are some ideas:

The main line is

"-".join(str(d.get(idx, "-")) for idx in range(1, 9))

which, given a dict d having indices as keys and corresponding fret numbers as values, construct the string representation.

It uses the dict.get method which allows for a default value of "-" when nothing corresponds in the given dict.

from collections import namedtuple

def construct_string(indices, frets):
    d = dict(zip(indices, frets))
    out = "-".join(str(d.get(idx, "-")) for idx in range(1, 9))
    return f"-{out}-"

String = namedtuple("Note", ["indices", "frets"])

strings = {
    "e": String([4, 5, 8], [5, 7, 7]),
    "B": String([3, 6], [5, 5]),
    "G": String([2, 7], [5, 5]),
    "D": String([1, 5], [7, 6]),
    "A": String([], []),
    "E": String([], []),
}

for string_name, string in strings.items():
    string_line = construct_string(string.indices, string.frets)
    print(f"{string_name}|{string_line}")

which prints:

e|-------5-7-----7-
B|-----5-----5-----
G|---5---------5---
D|-7-------6-------
A|-----------------
E|-----------------
Sign up to request clarification or add additional context in comments.

3 Comments

This is good. I'd suggest Note should be plural, Notes, and notes dict should be strings. Also I'm guessing the OP did not have 17 divisions per bar, but 8 with - spacers and end-caps. But this gets the important idea across of having a data structure for the grid and then build the printable output from that.
@Anentropic yes I don't know anything about guitar so I was expecting making some semantic mistakes. As you said the usage of a suitable data structure is the main point here.
@Anentropic is it more correct now?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.