You are not logged in.

#1 2008-02-20 21:50:45

mrcold
Member
Registered: 2008-01-24
Posts: 150

a bash script

I decided to learn how to program (for fun) and picked as my first language BASH because i figured it would be the one that is the most useful to me as a computer user.
Anyway, I started reading things yesterday, and came up with this little program which is a calculator for various types of chords(musical chords that is) I would appreciate it if someone would take a look at it and tell me how i did smile
perhaps a few pointers or suggestions? who knows.
Thanks

#! /bin/bash
clear
echo CHORD CALCULATOR 0.0
echo By Cody Loyd
echo 
echo
echo Please enter the root of your chord
echo Use lowercase letters and convert flats to enharmonic sharps
echo "(" Bb "->" "A#" "etc." ")"
echo For International chords, insert the key in which they appear
read ROOT
if [ "$ROOT" = "c" ]; then
    ONE="C"
    TWO="C#/Db"
    THREE="D"
    FOUR="D#/Eb"
    FIVE="E"
    SIX="F"
    SEVEN="F#/Gb"
    EIGHT="G"
    NINE="G#/Ab"
    TEN="A"
    ELEVEN="A#/Bb"
    TWELVE="B"
elif [ "$ROOT" =  "g" ]; then
    SIX="C"
    SEVEN="C#/Db"
    EIGHT="D"
    NINE="D#/Eb"
    TEN="E"
    ELEVEN="F"
    TWELVE="F#/Gb"
    ONE="G"
    TWO="G#/Ab"
    THREE="A"
    FOUR="A#/Bb"
    FIVE="B"

elif [ "$ROOT" = "f" ]; then
    EIGHT="C"
    NINE="C#/Db"
    TEN="D"
    ELEVEN="D#/Eb"
    TWELVE="E"
    ONE="F"
    TWO="F#/Gb"
    THREE="G"
    FOUR="G#/Ab"
    FIVE="A"
    SIX="A#/Bb"
    SEVEN="B"
elif [ "$ROOT" = "f#" ]; then
    SEVEN="C"
    EIGHT="C#/Db"
    NINE="D"
    TEN="D#/Eb"
    ELEVEN="E"
    TWELVE="F"
    ONE="F#/Gb"
    TWO="G"
    THREE="G#/Ab"
    FOUR="A"
    FIVE="A#/Bb"
    SIX="B"
elif [ "$ROOT" = "g#" ]; then
    FIVE="C"
    SIX="C#/Db"
    SEVEN="D"
    EIGHT="D#/Eb"
    NINE="E"
    TEN="F"
    ELEVEN="F#/Gb"
    TWELVE="G"
    ONE="G#/Ab"
    TWO="A"
    THREE="A#/Bb"
    FOUR="B"    
elif [ "$ROOT" = "a" ]; then
    FOUR="C"
    FIVE="C#/Db"
    SIX="D"
    SEVEN="D#/Eb"
    EIGHT="E"
    NINE="F"
    TEN="F#/Gb"
    ELEVEN="G"
    TWELVE="G#/Ab"
    ONE="A"
    TWO="A#/Bb"
    THREE="B"    
elif [ "$ROOT" = "a#" ]; then
    THREE="C"
    FOUR="C#/Db"
    FIVE="D"
    SIX="D#/Eb"
    SEVEN="E"
    EIGHT="F"
    NINE="F#/Gb"
    TEN="G"
    ELEVEN="G#/Ab"
    TWELVE="A"
    ONE="A#/Bb"
    TWO="B"    
elif [ "$ROOT" = "b" ]; then
    TWO="C"
    THREE="C#/Db"
    FOUR="D"
    FIVE="D#/Eb"
    SIX="E"
    SEVEN="F"
    EIGHT="F#/Gb"
    NINE="G"
    TEN="G#/Ab"
    ELEVEN="A"
    TWELVE="A#/Bb"
    ONE="B"    
elif [ "$ROOT" = "c#" ]; then
    TWELVE="C"
    ONE="C#/Db"
    TWO="D"
    THREE="D#/Eb"
    FOUR="E"
    FIVE="F"
    SIX="F#/Gb"
    SEVEN="G"
    EIGHT="G#/Ab"
    NINE="A"
    TEN="A#/Bb"
    ELEVEN="B"    
elif [ "$ROOT" = "d" ]; then
    ELEVEN="C"
    TWELVE="C#/Db"
    ONE="D"
    TWO="D#/Eb"
    THREE="E"
    FOUR="F"
    FIVE="F#/Gb"
    SIX="G"
    SEVEN="G#/Ab"
    EIGHT="A"
    NINE="A#/Bb"
    TEN="B"    
elif [ "$ROOT" = "d#" ]; then
    TEN="C"
    ELEVEN="C#/Db"
    TWELVE="D"
    ONE="D#/Eb"
    TWO="E"
    THREE="F"
    FOUR="F#/Gb"
    FIVE="G"
    SIX="G#/Ab"
    SEVEN="A"
    EIGHT="A#/Bb"
    NINE="B"    
elif [ "$ROOT" = "e" ]; then
    NINE="C"
    TEN="C#/Db"
    ELEVEN="D"
    TWELVE="D#/Eb"
    ONE="E"
    TWO="F"
    THREE="F#/Gb"
    FOUR="G"
    FIVE="G#/Ab"
    SIX="A"
    SEVEN="A#/Bb"
    EIGHT="B"


else
    
    echo Please try again, insert a root in lowercase, converting flats to enharmonic sharps
exit
fi
echo Please select the quality for $ROOT
OPTIONS="Major Minor Diminished Augmented MmSeventh SchoenbergChord Italian German French Neopolitan"
select opt in $OPTIONS; do
if [ "$opt" = "Major" ]; then
    echo $ONE - $FIVE - $EIGHT
    exit 
elif [ "$opt" = "Minor" ]; then
    echo $ONE - $FOUR - $EIGHT
    exit
elif [ "$opt" = "Diminished" ]; then
    echo $ONE - $FOUR - $SEVEN
    exit
elif [ "$opt" = "Augmented" ]; then
    echo $ONE - $FIVE - $NINE
    exit
elif [ "$opt" = "MmSeventh" ]; then
    echo $ONE - $FIVE - $EIGHT - $ELEVEN
    exit
elif [ "$opt" = "SchoenbergChord" ]; then
    echo ARE YOU FRIGGIN CRAZY????
    echo $ONE - $TWO - $THREE - $FOUR - $FIVE - $SIX - $SEVEN - $EIGHT - $NINE - $TEN - $ELEVEN - $TWELVE
    exit
elif [ "$opt" = "Italian" ]; then
    echo Itsa Musica!
    echo $SEVEN - $NINE - $ONE
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "German" ]; then
    echo $SEVEN - $NINE - $ONE - $FOUR
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "French" ]; then
    echo $SEVEN - $NINE - $ONE - $THREE
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "Neopolitan" ]; then
    echo CHOCOLATE
    echo VANILLA
    echo STRAWBERRRRRRRRY!
    echo $TWO - $SIX - $NINE
    echo usage tip: this chord is usually found in 1st inversion, meaning $SIX is in the bass
    exit
else
echo "More Chords will Be added Later"
fi
done

Offline

#2 2008-02-20 22:13:17

Allan
Pacman
From: Brisbane, AU
Registered: 2007-06-09
Posts: 11,385
Website

Re: a bash script

You might want to look at the case statement.  I think it is a much cleaner solution than all the elif statements.  Otherwise, not bad for first attempt.

Offline

#3 2008-02-20 23:03:00

mrcold
Member
Registered: 2008-01-24
Posts: 150

Re: a bash script

Allan wrote:

You might want to look at the case statement.  I think it is a much cleaner solution than all the elif statements.  Otherwise, not bad for first attempt.

thank you, I'll look it up smile

Offline

#4 2008-02-21 02:56:34

peets
Member
From: Montreal
Registered: 2007-01-11
Posts: 936
Website

Re: a bash script

One fun part of programming is avoiding repetition. I find repeating myself boring, but I'm sure my computer doesn't mind doing it for me. And it's actually a fun challenge to try and find abstractions.

Here's a little rewrite of the code based on this. Note: I suck at bash (or is it "bash sucks?")

#! /bin/bash

ROOT_SET=("c" "c#" "d" "d#" "e" "f" "f#" "g" "g#" "a" "a#" "b")

clear
echo CHORD CALCULATOR 0.0
echo By Cody Loyd
echo 
echo
echo Please enter the root of your chord
echo Use lowercase letters and convert flats to enharmonic sharps
echo "(" Bb "->" "A#" "etc." ")"
echo For International chords, insert the key in which they appear
read ROOT

ROOT_SHIFT=-1
for i in {0..11}; do
    if [ $ROOT = ${ROOT_SET[$i]} ]; then
        ROOT_SHIFT=$i
        break
    fi
done

if [ $ROOT_SHIFT -eq -1 ]; then
    echo Please try again, insert a root in lowercase, converting flats to enharmonic sharps
    echo legal values are: "${ROOT_SET[@]:0}"
    exit
fi

NOTES=( {0..11} ) # temporary values (I suck at Bash)
for i in {0..11}; do
    if [ $((i+ROOT_SHIFT)) -ge 12 ]; then
        NOTES[${i}]=${ROOT_SET[$((i+ROOT_SHIFT-12))]}
        #echo "$((i+1)) ${ROOT_SET[$((i+ROOT_SHIFT-12))]}" # damn it's ugly
    else
        #echo "$((i+1)) ${ROOT_SET[$((i+ROOT_SHIFT))]}"
        NOTES[${i}]=${ROOT_SET[$((i+ROOT_SHIFT))]}
    fi
done

ONE=${NOTES[1]}
TWO=${NOTES[2]}
THREE=${NOTES[3]}
FOUR=${NOTES[4]}
FIVE=${NOTES[5]}
SIX=${NOTES[6]}
SEVEN=${NOTES[7]}
EIGHT=${NOTES[8]}
NINE=${NOTES[9]}
TEN=${NOTES[10]}
ELEVEN=${NOTES[11]}
TWELVE=${NOTES[12]}

echo Please select the quality for $ROOT
OPTIONS="Major Minor Diminished Augmented MmSeventh SchoenbergChord Italian German French Neopolitan"
select opt in $OPTIONS; do
if [ "$opt" = "Major" ]; then
    echo $ONE - $FIVE - $EIGHT
    exit 
elif [ "$opt" = "Minor" ]; then
    echo $ONE - $FOUR - $EIGHT
    exit
elif [ "$opt" = "Diminished" ]; then
    echo $ONE - $FOUR - $SEVEN
    exit
elif [ "$opt" = "Augmented" ]; then
    echo $ONE - $FIVE - $NINE
    exit
elif [ "$opt" = "MmSeventh" ]; then
    echo $ONE - $FIVE - $EIGHT - $ELEVEN
    exit
elif [ "$opt" = "SchoenbergChord" ]; then
    echo ARE YOU FRIGGIN CRAZY????
    echo $ONE - $TWO - $THREE - $FOUR - $FIVE - $SIX - $SEVEN - $EIGHT - $NINE - $TEN - $ELEVEN - $TWELVE
    exit
elif [ "$opt" = "Italian" ]; then
    echo Itsa Musica!
    echo $SEVEN - $NINE - $ONE
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "German" ]; then
    echo $SEVEN - $NINE - $ONE - $FOUR
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "French" ]; then
    echo $SEVEN - $NINE - $ONE - $THREE
    echo usage tip: $NINE is usually in the bass
    exit
elif [ "$opt" = "Neopolitan" ]; then
    echo CHOCOLATE
    echo VANILLA
    echo STRAWBERRRRRRRRY!
    echo $TWO - $SIX - $NINE
    echo usage tip: this chord is usually found in 1st inversion, meaning $SIX is in the bass
    exit
else
echo "More Chords will Be added Later"
fi
done

You'd save a few lines by replacing every instance of $ONE with ${NOTES[1]}, etc.

Offline

#5 2008-02-21 03:28:34

mrcold
Member
Registered: 2008-01-24
Posts: 150

Re: a bash script

great!
I was wondering if there was a way to do that, but hadn't figured it out yet.
actually, i am looking through it an still havent' figured it out completely, but I can at least see what is happening
thanks

Last edited by mrcold (2008-02-21 03:34:28)

Offline

#6 2008-02-21 15:16:35

peets
Member
From: Montreal
Registered: 2007-01-11
Posts: 936
Website

Re: a bash script

Since I don't like Bash, but I like perl, here's some propaganda:

#!/usr/bin/perl
# usage: chords.pl <root> <chord name>
use strict;

my %roots = qw(c 0 c# 1 d 2 d# 3 e 4 f 5 f# 6 g 7 g# 8 a 9 a# 10 b 11);
my %chords = ("Major" => [1,5,8],
        "Minor" => [1,4,8],
        "Diminished" => [1,4,7],
        "Augmented" => [1,5,9],
        "Mm Seventh" => [1,5,8,11],
        "Shoenberg Chord" => [1,2,3,4,5,6,7,8,9,10,11,12],
        "Italian" => [7,9,1],
        "German" => [7,9,1,4],
        "French" => [7,9,1,3],
        "Neapolitan" => [2,6,9]
    );


my $root = shift @ARGV;
my $root_shift = $roots{$root};
defined $root_shift or die "'$root' is not a valid root.\n";

my @notes;
while(my($note, $n) = each %roots) {
    if($n - $root_shift < 0) {
        $notes[$n - $root_shift + 12] = $note;
    } else {
        $notes[$n - $root_shift] = $note;
    }
}

my $chord = join(" ", map(ucfirst, @ARGV));
my @numbers = @{$chords{$chord}};
@numbers or die "'$chord' is not a valid chord.\n";

print join(" - ", map($notes[$_ - 1], @numbers)) . "\n";

Offline

#7 2008-02-21 20:00:53

mrcold
Member
Registered: 2008-01-24
Posts: 150

Re: a bash script

peets wrote:

Since I don't like Bash, but I like perl, here's some propaganda:

#!/usr/bin/perl
# usage: chords.pl <root> <chord name>
use strict;

my %roots = qw(c 0 c# 1 d 2 d# 3 e 4 f 5 f# 6 g 7 g# 8 a 9 a# 10 b 11);
my %chords = ("Major" => [1,5,8],
        "Minor" => [1,4,8],
        "Diminished" => [1,4,7],
        "Augmented" => [1,5,9],
        "Mm Seventh" => [1,5,8,11],
        "Shoenberg Chord" => [1,2,3,4,5,6,7,8,9,10,11,12],
        "Italian" => [7,9,1],
        "German" => [7,9,1,4],
        "French" => [7,9,1,3],
        "Neapolitan" => [2,6,9]
    );


my $root = shift @ARGV;
my $root_shift = $roots{$root};
defined $root_shift or die "'$root' is not a valid root.\n";

my @notes;
while(my($note, $n) = each %roots) {
    if($n - $root_shift < 0) {
        $notes[$n - $root_shift + 12] = $note;
    } else {
        $notes[$n - $root_shift] = $note;
    }
}

my $chord = join(" ", map(ucfirst, @ARGV));
my @numbers = @{$chords{$chord}};
@numbers or die "'$chord' is not a valid chord.\n";

print join(" - ", map($notes[$_ - 1], @numbers)) . "\n";

smile
I know that what i wrote is not exactly what BASH is useful for i was just messing around with it. 
in any case, thanks.

Offline

#8 2008-02-21 23:29:18

peets
Member
From: Montreal
Registered: 2007-01-11
Posts: 936
Website

Re: a bash script

I'm just trying to say that Bash is not what's best for a first language. It's very good as a shell, but the scripts are not fun to write.

Since you're learning for fun, you can learn any language you like!

If you're a bit into math, I recommend a functional language as your first one (Lisp, Haskell, OCaml, etc.). It's a lot closer to the real world than imperative languages.

But, if you want to understand how your computer works "under the hood", maybe learn an imperative langage like assembly or C.

If you just want to tell your computer a sequence of things to do, you can learn a multi-paradigm high-level imperative language like Python.

Offline

Board footer

Powered by FluxBB