Thursday, March 23, 2023

Own Grandpa Modelling

The following are the lyrics to the song "I'm My Own Grandpa":

Now, many many years ago / When I was twenty three / I was married to a widow / Who was pretty as could be / This widow had a grown-up daughter / Had hair of red / My father fell in love with her / And soon the two were wed / This made my dad my son-in-law / And changed my very life / My daughter was my mother / 'Cause she was my father's wife / To complicate the matters / Even though it brought me joy / I soon became the father / Of a bouncing baby boy / My little baby then became / A brother-in-law to dad / And so became my uncle / Though it made me very sad / For if he was my uncle / That also made him the brother / Of the widow's grown-up daughter / Who, of course, was my step-mother / I'm my own grandpa / I'm my own grandpa / It sounds funny I know / But it really is so / I'm my own grandpa / My father's wife then had a son / That kept them on the run / And he became my grandchild / For he was my daughter's son / My wife is now my mother's mother / And it makes me blue / Because, she is my wife / She's my grandmother too / I'm my own grandpa / I'm my own grandpa / It sounds funny I know / But it really is so / I'm my own grandpa / Now, if my wife is my grandmother / Then, I am her grandchild / And every time I think of it / It nearly drives me wild / For now I have become / The strangest case you ever saw / As husband of my grandmother / I am my own grandpa / I'm my own grandpa / I'm my own grandpa / It sounds funny I know / But it really is so / I'm my own grandpa / I'm my own grandpa / I'm my own grandpa / It sounds funny I know / But it really is so / I'm my own grandpa

Describe the family tree of the narrator.

The narrator of the song is married to a widow who has a grown-up daughter. The narrator's father falls in love with and marries the grown-up daughter, making the narrator's father his son-in-law and the grown-up daughter his mother. The narrator then has a child with his mother, who becomes his uncle because he is the son of the narrator's father (who is also his son-in-law). The widow (the narrator's wife) has another child, who becomes the narrator's grandchild because he is the son of the narrator's daughter (who is also his mother). The narrator's wife is now the mother of the narrator's mother, making the narrator's wife his grandmother. This means that the narrator is the grandchild of his own wife.

Define a Javascript "Person" class that can keep track of these relationships, including self-grandfatherhood.

Here is an example of a JavaScript "Person" class that can keep track of the relationships described in the song "I'm My Own Grandpa":

class Person {
  constructor(name, mother, father, spouse, children) {
    this.name = name;
    this.mother = mother;
    this.father = father;
    this.spouse = spouse;
    this.children = children || [];
  }
  // getters and setters for each property
  getName() {
    return this.name;
  }
  setName(name) {
    this.name = name;
  }
  getMother() {
    return this.mother;
  }
  setMother(mother) {
    this.mother = mother;
  }
  getFather() {
    return this.father;
  }
  setFather(father) {
    this.father = father;
  }
  getSpouse() {
    return this.spouse;
  }
  setSpouse(spouse) {
    this.spouse = spouse;
  }
  getChildren() {
    return this.children;
  }
  addChild(child) {
    this.children.push(child);
  }
  // method to check if the person is their own grandparent
  isOwnGrandparent() {
    return this.mother && this.mother.father && this.mother.father.name === this.name;
  }
}

To create a new person, you would use the Person class like this:

const john = new Person('John', null, null, null);
const jane = new Person('Jane', null, null, null);
john.setSpouse(jane);
jane.setSpouse(john);
const mary = new Person('Mary', jane, john, null);
jane.addChild(mary);
john.addChild(mary);
const bob = new Person('Bob', mary, null, null);
mary.addChild(bob);
console.log(bob.isOwnGrandparent()); // true

This creates a new Person object for each member of the family, with the appropriate relationships between them. The isOwnGrandparent() method can then be used to check if the person is their own grandparent, as in the song.

What would be a good way to model this in Python?

Here is an example of how you could model the family tree described in the song "I'm My Own Grandpa" in Python:

class Person:
  def __init__(self, name, mother, father, spouse, children=None):
    self.name = name
    self.mother = mother
    self.father = father
    self.spouse = spouse
    self.children = children or []
  # method to check if the person is their own grandparent
  def is_own_grandparent(self):
    return self.mother and self.mother.father and self.mother.father.name == self.name
# create a new person for each member of the family
john = Person('John', None, None, None)
jane = Person('Jane', None, None, None)
# set the spouses for John and Jane
john.spouse = jane
jane.spouse = john
# create a new person for Mary and set her parents
mary = Person('Mary', jane, john, None)
jane.children.append(mary)
john.children.append(mary)
# create a new person for Bob and set his parent
bob = Person('Bob', mary, None, None)
mary.children.append(bob)
# check if Bob is his own grandparent
print(bob.is_own_grandparent())  # True

This creates a new Person object for each member of the family, with the appropriate relationships between them. The is_own_grandparent() method can then be used to check if the person is their own grandparent, as in the song.

Could we model this in Racket?

Yes, you can model the family tree described in the song "I'm My Own Grandpa" in Racket using a similar approach to the examples given in JavaScript and Python. Here is an example of how you could do this:

# define a person struct with fields for name, mother, father, spouse, and children
(struct person (name mother father spouse children))
# define a function to check if a person is their own grandparent
(define (is-own-grandparent? person)
  (and (person-mother person)
       (person-father (person-mother person))
       (string=? (person-name person)
                 (person-name (person-father (person-mother person))))))
# create a new person for each member of the family
(define john (person "John" #f #f #f #f))
(define jane (person "Jane" #f #f #f #f))
# set the spouses for John and Jane
(set-person-spouse! john jane)
(set-person-spouse! jane john)
# create a new person for Mary and set her parents
(define mary (person "Mary" jane john #f #f))
(set-person-children! jane (cons mary (person-children jane)))
(set-person-children! john (cons mary (person-children john)))
# create a new person for Bob and set his parent
(define bob (person "Bob" mary #f #f #f))
(set-person-children! mary (cons bob (person-children mary)))
# check if Bob is his own grandparent
(is-own-grandparent? bob)  ; returns #t

This creates a new person struct for each member of the family, with the appropriate relationships between them. The is-own-grandparent? function can then be used to check if the person is their own grandparent, as in the song.

Why did you not define the setter functions? Is this automatic in Racket or did you just forget?

In the Racket example, I did not define setter functions for the fields in the person struct because Racket automatically generates setter functions for each field in a struct. For example, the set-person-spouse! function used in the code is automatically generated by Racket when the person struct is defined.

In general, when you define a struct in Racket, the setter functions are named set-<struct-name>-<field-name>!. So, for the person struct, the setter function for the spouse field would be set-person-spouse!, and the setter function for the children field would be set-person-children!.

You can use these setter functions to update the values of the fields in a person struct. For example, the code (set-person-spouse! john jane) sets the spouse field of the john struct to the value of the jane struct.

This is right, as per the Racket docs. I didn’t know before it told me, though. See also the Wikipedia page for the song, and this music video of it.

No comments:

Post a Comment