3
\$\begingroup\$

Original question: Node.JS Automatic Poem Generator


This is a followup to the question from above. I am only reposting, as my new code was written from the ground up, and is only slightly similar.

This code generates (sentences of) random poems.

// Node.JS/JavaScript Poem Generator
// This only generates simple sentences, not full poems.

// First of all, we need some words. I don't include every part of speech; just the useful ones.
// In addition, I mostly chose words that were abstract, pertaining to emotions, or artistic.

// a = noun singular
// b = noun plural
// c = pronoun singular
// d = pronoun plural
// e = verb action
// f = verb linking singular
// g = verb linking plural
// h = adjective
// i = adjective possessive
// j = interjection
// k = preposition
// l = adjverb

var
a = "darkness,morning,light,feeling,beauty,love,hatred,expression,message,happiness,sadness,anger,frustration".split(","),
b = "mornings,lights,feelings,beauties,messages".split(","),
c = "he,she,it,I".split(","),
d = "them".split(","),
e = "ran,went,vanished,died,lived,appeared,disappeared,increased,decreased,augmented,changed".split(","),
f = "is,was,had been,will be,could be,might be,should have been,would have been,could have been,should be,would be".split(","),
g = "are,were,had been,will be,could be,might be,should have been,would have been,could have been,should be,would be".split(","),
h = "abstract,mysterious,permanent,unfortunate,intricate,confusing,true,false,fake,a lie,a stranger,a friend,serene,confusing,an enemy,terrible,enchanting,mine,yours,his,hers,theirs,ours,fortunate,understood,mine,interesting,mutual,artistic,musical".split(","),
i = "the,my,your,his,her,their,our,everybody's".split(","),
j = "ha,ah,aah,eh,er,hmm,yah,oh".split(","),
k = "with,from,during,included,among,by,about,between,after,along with".split(","),
l = "quickly,fleetingly,continuously".split(",");

// A short helper function to generate a random word based on the type given to it.

function newWord(type) {
  switch (type) {
    case "a":
      return a[Math.floor(Math.random()*a.length)];
    case "b":
      return b[Math.floor(Math.random()*b.length)];
    case "c":
      return c[Math.floor(Math.random()*c.length)];
    case "d":
      return d[Math.floor(Math.random()*d.length)];
    case "e":
      return e[Math.floor(Math.random()*e.length)];
    case "f":
      return f[Math.floor(Math.random()*f.length)];
    case "g":
      return g[Math.floor(Math.random()*g.length)];
    case "h":
      return h[Math.floor(Math.random()*h.length)];
    case "i":
      return i[Math.floor(Math.random()*i.length)];
   case "j":
      return j[Math.floor(Math.random()*j.length)];
    case "k":
      return k[Math.floor(Math.random()*k.length)];
    case "l":
      return l[Math.floor(Math.random()*l.length)];
  }
}

// To make the program more modular, you can create sentence structures and call them with this
// function. It takes a string such as "i a f h.", and replaces the lower case letters with
// a new word, as chosen by the above function.

function newSentence(format) {
  var sentence = "";
  for (var token = 0; token < format.length; token++) {
    if (-1 == "abcdefghijkl".indexOf(format[token])) {
      sentence += format[token];
    } else {
      sentence += newWord(format[token]);
    }
  }
  return sentence.charAt(0).toUpperCase() + sentence.slice(1);
}

// Right now, the code only uses one sentence structure, but can interpret many more.

console.log(newSentence("i a f h."));

In my previous post, the only response I received was pertaining to the poems themselves. Although the advice was appreciated, I am more concerned about the code itself.

Several things bug me about this code already, but I don't know a more elegant solution:

  1. The newWord() function seems unnecessary. Using eval() could make the code a lot shorter and more elegant, but everything I have learned about JS has told me to avoid eval() at all costs.

  2. Is a CSV really the best way to define a list. Defining a list in a normal was (["he","she","it","I"]) is much longer.

Any advice would greatly be appreciated.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

CSV strings or arrays?

You should consider using a JSON file instead of either. Currently, the only words you can use are ones that are hardcoded into your poem generator. You could make your code more reusable by allowing a user to use whatever word lists they wanted by loading the words from a file:

words.json

{
  "a": [
    "darkness",
    "morning",
    "light",
    "feeling",
    "beauty",
    "love",
    "hatred",
    "expression",
    "message",
    "happiness",
    "sadness",
    "anger",
    "frustration"
  ],
  "b": [
    "mornings",
    "lights",
    "feelings",
    "beauties",
    "messages"
  ],
  "c": [
    "he",
    "she",
    "it",
    "I"
  ],
  "d": [
    "them"
  ],
  "e": [
    "ran",
    "went",
    "vanished",
    "died",
    "lived",
    "appeared",
    "disappeared",
    "increased",
    "decreased",
    "augmented",
    "changed"
  ],
  "f": [
    "is",
    "was",
    "had been",
    "will be",
    "could be",
    "might be",
    "should have been",
    "would have been",
    "could have been",
    "should be",
    "would be"
  ],
  "g": [
    "are",
    "were",
    "had been",
    "will be",
    "could be",
    "might be",
    "should have been",
    "would have been",
    "could have been",
    "should be",
    "would be"
  ],
  "h": [
    "abstract",
    "mysterious",
    "permanent",
    "unfortunate",
    "intricate",
    "confusing",
    "true",
    "false",
    "fake",
    "a lie",
    "a stranger",
    "a friend",
    "serene",
    "confusing",
    "an enemy",
    "terrible",
    "enchanting",
    "mine",
    "yours",
    "his",
    "hers",
    "theirs",
    "ours",
    "fortunate",
    "understood",
    "mine",
    "interesting",
    "mutual",
    "artistic",
    "musical"
  ],
  "i": [
    "the",
    "my",
    "your",
    "his",
    "her",
    "their",
    "our",
    "everybody's"
  ],
  "j": [
    "ha",
    "ah",
    "aah",
    "eh",
    "er",
    "hmm",
    "yah",
    "oh"
  ],
  "k": [
    "with",
    "from",
    "during",
    "included",
    "among",
    "by",
    "about",
    "between",
    "after",
    "along with"
  ],
  "l": [
    "quickly",
    "fleetingly",
    "continuously"
  ]
}

To load a JSON file, Node has a really convenient built in function require that loads a JSON file into an object:

var words = require("./words.json");
console.log(words.a[0]); // darkness

* You should also consider giving more informative names to your word arrays (a could be nouns, b could be plural_nouns, etc...). That way another person could more easily use your poem generator with their own words.

Massive switch statement

Your switch statement is kind of long. It also needs to know about each individual word type to work. If you wanted to add another word type, you would need to add that case to your switch statement. A better strategy would be to use a javascript object {} to map word types to lists of words. That way when a new word type is added, your program will automatically be able to recognize it. This also will work well with a words object loaded from JSON:

function newWord(type) {
  let list = words[type]

  if (list === undefined) // unrecognized symbol
    return type;
  else
    return list[Math.floor(Math.random()*list.length)]
}
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.