shuann-book

URL to ZIP: https://drive.google.com/file/d/1RQSg3IoQqV_9MWc9p3Vng2feqgH-IsUT/view?usp=sharing

Title: A Guide to Absurd Movies

One sentence description: Explore absolutely absurd movies with this chapter. Yet remember the biggest challenge is where to find them.

I first had the idea of making a recipe book for creating new movies. For the ingredients, I would just throw in some random director, actors, writers ect., and then you will generate a random plot to go along with it. However, as I discovered some resources online containing real user reviews I wanted to include that as well. Thus, eventually, my chapter become something like a review book on non-existing movies: it is the interplay between the fake and the real that I am personally very interested in.

The entire project is generated based on Markov chains because I have to have completely bazar plot lines which the computer think marks as possible with little intervention as possible (i.e. predefined grammar). However, also due to this technique that I am using, I had to spend hours and hours cleaning up the data that I was feeding into the program. For example, I had to change all the names of the male protagonists to Chris and those of the female protagonists to Jade just so that names that only appear in one movie would not break the Markov chain. I also had to do a lot of filtering so that the plot content is not too over the place that two generated sentences adjacent to each other make no sense.

you can see that here, too many names and proper nouns are breaking the reading experience.

A lot better with cleaned up data, though more needed to be done.

Also, to make sure the first sentence makes sense, I need to incorporate many validators so that, for example, the sentence will always contain a determiner, does not start with a conjunction, etc. Moreover, I also tried to make sure that the pronoun matches the sex of the person that was named. Ex. "him" is changed into "her" because the determiner is identified as female in the first sentence.

Screenshots of the book pages: 

 var metaData;
var plot;
var posReview, negReview;
var titleTracker = 1;
var dirList = [];
var writerList = [];
var actorList = [];
var plotList = [];
 
var linesPlot = [];
var linesReview = [];
var markovPlot, x = 160, y = 240;
var markovPosReview, markovNegReview, x1 = 160, y1 = 200;
 
var bannedBeginner = ["He", "His", "Her", "She", "They", "Their", "We", "Another", "Suddenly", "However", "The next"];
var bannedMid = ["then", "as well", "also", "not only"];
var male = ["he", "Chris", "Chris's", "him", "male", "man", "his", "gentlemen", "boy", "himself"];
var female = ["she", "Jade", "Jade's", "her", "female", "woman", "her", "lady", "girl", "herself"];
 
var finalReivew = [];
var curDir = [];
var curActor = [];
var curWriter = [];
 
var movies = [];
 
function preload(){
  metaData = loadJSON("movieDetails.json");
 
  plot = loadStrings('illusion.txt');
  posReview = loadStrings('posReview.txt');
  negReview = loadStrings('negReview.txt');
}
 
function setup() {
  createCanvas(600, 600);
  textFont('times', 16);
  textAlign(LEFT);
 
  // create a markov model w' n=4
  markovTitle = new RiMarkov(2);
  markovPlot = new RiMarkov(3);
  markovPosReview = new RiMarkov(4);
  markovNegReview = new RiMarkov(4);
 
  // load text into the model
  markovTitle.loadText(plot.join(' '));
  markovPlot.loadText(plot.join(' '));
  markovPosReview.loadText(posReview.join(' '));
  markovNegReview.loadText(negReview.join(' '));
 
  extractInfo();
 
  for (var i = 0; i < 15; i++){
    generate(i);
  }
 
  // Create a JSON Object, fill it with the Poems.
  var myJsonObject = {};
  myJsonObject.movies = movies;
  // console.log(myJsonObject);
 
  // Make a button. When you press it, it will save the JSON.
  createButton('SAVE POEMS BUTTON')
    .position(10, 10)
    .mousePressed(function() {
      saveJSON(myJsonObject, 'myPoems.json');
    });
}
 
function combineText(index) {
  var finalPlot = linesPlot.join(' ');
  for (var i = 0; i < linesReview.length; i++){
    finalReivew[i] = linesReview[i].join(' ');
  }
 
  var title = "Absurd Moive No." + titleTracker;
  titleTracker += 1;
 
  movies[index] = new moiveInfo(title, curDir, curActor, curWriter, finalPlot, finalReivew);
  console.log(movies[index]);
}
 
function generate(index) {
  randBasicInfo();
 
  linesPlot = markovPlot.generateSentences(2);
  checkPlot();
  checkAgreement();
 
  for (var i = 0; i < 3; i++){
    if (random() < 0.7){
      linesReview[i] = markovNegReview.generateSentences(random([3, 4]));
    } else {
      linesReview[i] = markovPosReview.generateSentences(random([2, 3, 4]));
    }
  }
 
  combineText(index);
}
 
//generate basic movie setp info
function randBasicInfo(){
  curDir = [];
  curActor = [];
  curWriter = [];
  var dirNum = 1;
  var actNum = random([3, 4, 4]);
  var wriNum = random([1, 2, 2]);
 
  for (var a = 0; a < dirNum; a++){
    curDir[a] = random(dirList);
  }
 
  for (var b = 0; b < actNum; b++){
    curActor[b] = random(actorList);
  }
 
  for (var c = 0; c < wriNum; c++){
    curWriter[c] = random(writerList);
  }
}
 
function checkPlot() {
  //get all words in the frist sentence
  var sentence1 = linesPlot[0].split(' ');
 
  //replace first sentence when it begins with pronoun
  if (checker(sentence1[0], bannedBeginner) || checkConjunction(sentence1[0])){
 
    linesPlot[0] = markovPlot.generateSentence();
    checkPlot();
  } else {
    //look at each word in the sentence
    for (var i = 0; i < sentence1.length; i++){
      sentence1[i] = RiTa.trimPunctuation(sentence1[i]);
    }
    // console.log(sentence1);
    // console.log("here");
 
    // if (checker(sentence1, bannedMid) && checker(sentence1, charNames) === false){
    //   console.log(linesPlot[0]);
    //   linesPlot[0] = markovPlot.generateSentence();
    //   console.log(linesPlot[0]);
    // }
 
    if (checker(sentence1, bannedMid)){
      linesPlot[0] = markovPlot.generateSentence();
      checkPlot();
    }
 
    if (checkDeterminer(sentence1) === false){
      linesPlot[0] = markovPlot.generateSentence();
      checkPlot();
    }
  }
}
 
// https://stackoverflow.com/questions/37428338/check-if-a-string-contains-any-element-of-an-array-in-javascript
function checker(value, ban) {
  for (var i = 0; i < ban.length; i++) { if (value.indexOf(ban[i]) > -1) {
      return true;
    }
  }
  return false;
}
 
function checkDeterminer(value){
  for (var a = 0; a < value.length; a++){
    if (RiTa.getPosTags(value[a]) == "dt"){
      return true;
    }
  }
  return false;
}
 
function checkConjunction(value){
  var tag = RiTa.getPosTags(value);
  for (var i = 0; i < tag.length; i++){
    if (tag[i] === "in" || tag[i] === "cc"){
      return true;
    }
  }
  return false;
}
 
function checkAgreement() {
  var sex = null;
  // sentence1Agg();
  // sentence2Agg();
 
  var sentence1 = linesPlot[0].split(' ');
  var sentence2 = linesPlot[1].split(' ');
 
  for (var i = 0; i < sentence1.length; i++){ sentence1[i] = RiTa.trimPunctuation(sentence1[i]); if (sex === null){ if (male.indexOf(sentence1[i]) > -1){
        sex = "M";
      }
      if (female.indexOf(sentence1[i]) > -1){
        sex = "F";
      }
    }
  }
 
  for (var a = 0; a < sentence1.length; a++){ if (RiTa.getPosTags(sentence1[a]) == "prp"){ if (male.indexOf(sentence1[a]) > -1 && sex === "F"){
        var index = male.indexOf(sentence1[a]);
        sentence1[a] = female[index];
      }
 
      if (female.indexOf(sentence1[a]) > -1 && sex === "M"){
        var index = male.indexOf(sentence1[a]);
        sentence1[a] = male[index];
      }
    }
  }
 
  linesPlot[0] = sentence1.join(' ') + ".";
}
 
function moiveInfo(title, dir, actor, writer, plot, reviews){
  this.title = title;
  this.direc = dir;
  this.actor = actor;
  this.writer = writer;
  this.plot = plot;
  this.reviews = reviews;
}
 
function extractInfo(){
  console.log(metaData.results.length);
  for (var i = 0; i < metaData.results.length; i++){ if (metaData.results[i].imdb.rating >= 8){
      //extract the names of directors on file for all movies with imdb rating > 8
      if (metaData.results[i].director != null){
        if (metaData.results[i].director.length > 1){
          var dirArray = metaData.results[i].director.split(', ');
          for (var a = 0; a < dirArray.length; a++){ append(dirList, dirArray[a]); } } else { var dirArray = metaData.results[i].director; append(dirList, dirArray); } } if (metaData.results[i].writers != null){ if (metaData.results[i].writers.length >= 1){
          for (var b = 0; b < metaData.results[i].writers.length; b++){ append(writerList, metaData.results[i].writers[b]); } } } if (metaData.results[i].actors != null){ if (metaData.results[i].actors.length >= 1){
          for (var c = 0; c < metaData.results[i].actors.length; c++){
            append(actorList, metaData.results[i].actors[c]);
          }
        }
      }
    }
  }
}

Sources:

review.json from: https://github.com/Edmond-Wu/Movie-Reviews-Sentiments

Plot summary dataset from: http://www.cs.cmu.edu/~ark/personas/

Example movie dataset from: https://docs.mongodb.com/charts/master/tutorial/movie-details/prereqs-and-import-data/