[QUIZ] Twitter Personalities (#208)

D

Daniel Moore

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this
quiz until 48 hours have elapsed from the time this message was
sent.

2. Support Ruby Quiz by submitting ideas and responses
as often as you can!
Visit: http://rubyquiz.strd6.com/suggestions

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

RSS Feed: http://rubyquiz.strd6.com/quizzes.rss

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Twitter Personalities (#208)

Merhaba Rubyists,

This week's quiz is to create a program that will generate messages
140 characters in length. There primary use will be to create a
Twitter "personality". At the end of the quiz period these
"personalities" will be unleashed on the internet and we'll see how
they do in the wild.

The programs will consist of two parts: a component for interacting
with Twitter, and a top secret "personality" module.

For the Twitter interface component there will be no no-spoiler
period. Please feel encouraged to discuss different libraries or
methods on the mailing list. Let's all work together to find the best
interface.

The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.


Have Fun!
 
J

Joshua Collins

[Note: parts of this message were removed to make it a legal post.]

This Quiz sounds fun!

I wish I knew more about Ruby than I do now. I would participate in this
one, but I am a beginner rubyist :-(

Anyhow, I can not wait to see the results. Good luck to everyone
participating!


JC
 
J

James Gray

This Quiz sounds fun!

I wish I knew more about Ruby than I do now. I would participate in =20=
this one, but I am a beginner rubyist :-(

Anyhow, I can not wait to see the results. Good luck to everyone
participating!

This is an almost perfect quiz for a beginner! Don't give up!

Use it as a chance to stretch your skills.

Try this:

1. Build a funny saying in a String
2. Replace some words in that saying with variables that hold the =20
words you removed
3. Adjust each variable so it gets two or three different words that =20=

all could fit the saying, selected randomly

It's just like reverse Madlibs. You may get more ideas to keep =20
improving it too.

It's not a spoiler to get help on the Twitter side, or you can just =20
skip that part completely. Don't be afraid to change the task to suit =20=

your skill. If you learn something, you win.

You can even ask us questions on the personality side, just be clever =20=

in avoiding spoiler material. "Hey guys, I'm building a new =20
navigation system for NASA's next generation rocket and it needs to =20
randomly choose between three directions=85" We're here to help. :)

"Never give up! Never surrender!"

James Edward Gray II=
 
B

Bill Kelly

From: "Daniel Moore said:
The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.

So... to clarify, the personality component is not replying
to--or seeing--other messages as input, but is merely
producing a sequence of 140 character messages determined
solely according to its internal black box state?


Regards,

Bill
 
J

Justin Collins

Bill said:
So... to clarify, the personality component is not replying
to--or seeing--other messages as input, but is merely
producing a sequence of 140 character messages determined
solely according to its internal black box state?


Regards,

Bill

I don't think that is a necessary restriction, as it "can take any
inputs." I will interpret that to mean you can feed in whatever you
would like - a dictionary or Shakespeare, for example.

-Justin
 
D

Daniel Moore

Joshua,

James has some great suggestions and I couldn't have said it better.
One of the best ways to learn more about Ruby is to dive in. You may
find out that it is easier than you imagine. If you get stuck on a
particular issue you can search the web or ask on the mailing list;
there are many great resources and lots of people interested in
helping out.

This is an almost perfect quiz for a beginner! =A0Don't give up!

Use it as a chance to stretch your skills.

Try this:

1. =A0Build a funny saying in a String
2. =A0Replace some words in that saying with variables that hold the word= s you
removed
3. =A0Adjust each variable so it gets two or three different words that a= ll
could fit the saying, selected randomly

It's just like reverse Madlibs. =A0You may get more ideas to keep improvi= ng it
too.

It's not a spoiler to get help on the Twitter side, or you can just skip
that part completely. =A0Don't be afraid to change the task to suit your
skill. =A0If you learn something, you win.

You can even ask us questions on the personality side, just be clever in
avoiding spoiler material. =A0"Hey guys, I'm building a new navigation sy= stem
for NASA's next generation rocket and it needs to randomly choose between
three directions=85" =A0We're here to help. =A0:)

"Never give up! =A0Never surrender!"

James Edward Gray II


--=20
-Daniel
http://strd6.com
 
D

Daniel Moore

Bill,

The personality component can see other messages as input and use
those to determine the next message to provide. Of course, in order
for the component to see the replies and other messages they would
need to be gathered and passed in as arguments in some form.

If you like you can share the techniques for gathering these messages
with the mailing list. The goal is to make it as easy as possible to
focus on the "personality" part without worrying about the
nitty-gritty of interfacing with Twitter. Additionally sharing
information on available libraries or general techniques will help all
the solutions to be better.
 
J

Joshua Collins

[Note: parts of this message were removed to make it a legal post.]

I will give the Quiz a shot. After all, I will surely learn from it :)

Thanks for the encouragement guys!
 
S

Sandro Paganotti

[Note: parts of this message were removed to make it a legal post.]

Wow !! Absolutely great quiz ! :D
 
S

Srijayanth Sridhar

[Note: parts of this message were removed to make it a legal post.]

So the "personality" is just a random message, perhaps a Clint Eastwood
quote or something?

Jayanth
 
J

Justin Collins

Daniel said:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this
quiz until 48 hours have elapsed from the time this message was
sent.

2. Support Ruby Quiz by submitting ideas and responses
as often as you can!
Visit: http://rubyquiz.strd6.com/suggestions

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

RSS Feed: http://rubyquiz.strd6.com/quizzes.rss

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Twitter Personalities (#208)

Merhaba Rubyists,

This week's quiz is to create a program that will generate messages
140 characters in length. There primary use will be to create a
Twitter "personality". At the end of the quiz period these
"personalities" will be unleashed on the internet and we'll see how
they do in the wild.

The programs will consist of two parts: a component for interacting
with Twitter, and a top secret "personality" module.

For the Twitter interface component there will be no no-spoiler
period. Please feel encouraged to discuss different libraries or
methods on the mailing list. Let's all work together to find the best
interface.

The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.


Have Fun!

Posting to Twitter, I found, was pretty straightforward using the
Twitter4r gem, although it only worked for me under Ruby 1.9:

require 'twitter'
client = Twitter::Client.new :login => "myname", :password => "mypassword"
client.status :post, "Working on Ruby Quiz."


I hope that helps anyone who might have been hesitant because of the
Twitter interface part.

-Justin
 
J

James Gray

So the "personality" is just a random message, perhaps a Clint
Eastwood
quote or something?

It is if you want it to be. :)

If you would prefer to be trickier, you could try to build intelligent
replies to things people say.

James Edward Gray II
 
S

Sandro Paganotti

[Note: parts of this message were removed to make it a legal post.]

Ok, I've just finished mine... it was a really crazy experience... now I'm
going to create a twitter account for it and generate some random phrases
with different personalities :D
 
P

Phlip

Sandro said:
[Note: parts of this message were removed to make it a legal post.]

Ok, I've just finished mine... it was a really crazy experience... now I'm
going to create a twitter account for it and generate some random phrases
with different personalities :D

You mean like "The Policeman's Beard is Half-Constructed"?
 
S

Sandro Paganotti

[Note: parts of this message were removed to make it a legal post.]

Sort of :p (here's the bot account: https://twitter.com/twsapiens)

Sandro


Sandro said:
[Note: parts of this message were removed to make it a legal post.]

Ok, I've just finished mine... it was a really crazy experience... now I'm
going to create a twitter account for it and generate some random phrases
with different personalities :D

You mean like "The Policeman's Beard is Half-Constructed"?
 
J

Justin Collins

Justin said:
Daniel said:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this
quiz until 48 hours have elapsed from the time this message was
sent.

2. Support Ruby Quiz by submitting ideas and responses
as often as you can!
Visit: http://rubyquiz.strd6.com/suggestions

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

RSS Feed: http://rubyquiz.strd6.com/quizzes.rss

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Twitter Personalities (#208)

Merhaba Rubyists,

This week's quiz is to create a program that will generate messages
140 characters in length. There primary use will be to create a
Twitter "personality". At the end of the quiz period these
"personalities" will be unleashed on the internet and we'll see how
they do in the wild.

The programs will consist of two parts: a component for interacting
with Twitter, and a top secret "personality" module.

For the Twitter interface component there will be no no-spoiler
period. Please feel encouraged to discuss different libraries or
methods on the mailing list. Let's all work together to find the best
interface.

The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.


Have Fun!

Posting to Twitter, I found, was pretty straightforward using the
Twitter4r gem, although it only worked for me under Ruby 1.9:

require 'twitter'
client = Twitter::Client.new :login => "myname", :password =>
"mypassword"
client.status :post, "Working on Ruby Quiz."


I hope that helps anyone who might have been hesitant because of the
Twitter interface part.

-Justin


So, here is my full solution, which just pulls transcriptions of
Dijkstra's notes and tries to extract decent quotes. Also attempts to
find relavent replies. Works most of the time. You can see some results
at http://twitter.com/ewdbot and get a nicer-looking version from
http://gist.github.com/125781

#A little Twitter thing to post random quotes from Edsger Dijkstra

require 'yaml'
require 'open-uri'
require 'twitter' #twitter4r gem
require 'hpricot'

class DijkstraQuote
class << self

#Match the website's naming scheme
def random_ewd
(rand(1289) + 30).to_s.rjust(4, "0")
end

#Get a random quote
def get_quote
quote = nil
while quote.nil? do
quote = fetch random_ewd
end

quote
end

#Get a random quote from the specified set of notes
def fetch ewd

#Check if we've already retrieved this set of notes
if File.exists? "ewd#{ewd}"
quotes = YAML.load_file "ewd#{ewd}"
quotes[rand quotes.length]
else
$stderr.puts "Fetching EWD#{ewd}..." if $DEBUG

#Fetch a transcript of Dijkstra's notes
begin
file =
open("http://www.cs.utexas.edu/~EWD/transcriptions/EWD#{ewd[0,2]}xx/EWD#{ewd}.html")
{ |f| Hpricot(f) }
rescue OpenURI::HTTPError
$stderr.puts "Not found" if $DEBUG
return nil
end

text = file.to_plain_text

#Pick some sentences that seem good
lines = text.split(/\.(?:\s+|\n+)/).map do |l|
l.gsub(/\t|\n|\r/, " ").squeeze(" ").strip
end.select do |l|
l.length > 40 and l.length < 140 and l[0,1] ==
l[0,1].upcase and l[-3, 3] != "viz"
end

#Cache them for later
File.open "ewd#{ewd}", "w" do |f|
YAML.dump lines, f
end

#Return a random sentence
lines[rand lines.length]
end
end

#(Very crudely) tries to find a quote that is related to the
message.
#Note that this only searches the cache.
def find_related message

#Get the longer words
words = message.gsub(/[^a-zA-Z ]/, "").split.select { |w|
w.length > 4 }

quote = nil
if words.length > 0
word = /#{Regexp.union(words)}/i

#Check local files for the search word
Dir.glob("ewd*").find do |f|
text = File.read f
if text =~ word

#Get the list of quotes and grab one
quotes = YAML.load_file f
matches = quotes.grep word
quote = matches[rand(matches.length)]
else
false
end
end
else
quote = get_quote
end

quote
end
end
end

#Post to Twitter
class DijkstraTwitter

def initialize
@twitter = Twitter::Client.new :login => "?", :password => "?"
end

#Post a random quote. If _ask_ is true, asks for approval first
def post_random ask = false
quote = DijkstraQuote.get_quote

if ask and ask_permission("Would you like to post this:
\"#{quote}\"") or not ask
@twitter.status :post, quote
end
end

#Check unanswered @ewd messages and come up with responses
def post_replies ask = false
require 'set'

#Keep track of what has been replied to already
if File.exist? "ewdreplies"
replied = YAML.load_file "ewdreplies"
else
replied = Set.new
end

replies = @twitter.status:)replies)

replies.each do |status|
status_id = status.id.to_s
next if replied.include? status_id
message = status.text
user = status.user.screen_name
if reply_to message, user, ask
replied << status_id
end
end

File.open "ewdreplies", "w" do |f|
YAML.dump replied, f
end
end

#Send a reply if we can find one
def reply_to message, sender, ask = false
puts "Responding to \"#{message}\""

quote = DijkstraQuote.find_related message
if not quote
puts "Nothing related. Skipping."
return false
elsif ask and ask_permission("Would you like to post this:
\"#{quote}\"") or not ask
response = "@#{sender} #{quote}"
if response.length > 140
response = response[0,140]
end

@twitter.status:)post, "@#{sender} #{quote}")
true
else
if ask and ask_permission "Ignore this reply?"
true
else
false
end
end
end

#Ask if the user would like to post the quote which was found
def ask_permission message
puts message

response = nil
until response =~ /^(y|n)/i
print "(Y/N): "
response = gets
end

$1.downcase == "y"
end
end

#Try it out
puts DijkstraQuote.get_quote

#dt = DijkstraTwitter.new
#dt.post_random true
#dt.post_replies true


My favorite so far: "In this sense, Programming = Mathematics + Murphy's
Law"

-Justin
 
C

Chris Shea

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz:

1.  Please do not post any solutions or spoiler discussion for this
quiz until 48 hours have elapsed from the time this message was
sent.

2.  Support Ruby Quiz by submitting ideas and responses
as often as you can!
Visit:http://rubyquiz.strd6.com/suggestions

3.  Enjoy!

Suggestion:  A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion.  Please reply to
the original quiz message, if you can.

RSS Feed:http://rubyquiz.strd6.com/quizzes.rss

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Twitter Personalities (#208)

Merhaba Rubyists,

This week's quiz is to create a program that will generate messages
140 characters in length. There primary use will be to create a
Twitter "personality". At the end of the quiz period these
"personalities" will be unleashed on the internet and we'll see how
they do in the wild.

The programs will consist of two parts: a component for interacting
with Twitter, and a top secret "personality" module.

For the Twitter interface component there will be no no-spoiler
period. Please feel encouraged to discuss different libraries or
methods on the mailing list. Let's all work together to find the best
interface.

The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.

Have Fun!

Here's the twitter "personality" I made: http://twitter.com/iloveweather

It posts about the weather conditions of a random US city. The phrase
list needs some expanding, and there's a little code to clean up
before I post it. It was pretty fun, and I'm really enjoying seeing
tweets like "Step outside, Bliss. It's nice." and "It's days like this
that make people happy to be in Beverly."

It doesn't do replies (yet).

More to come,
Chris
 
T

Thorsten Hater

Hi,

here my implementation of a Markov chain based text generator for Twitter.

class MarkovText

def initialize file
@word_map = {}
do_preprocessing file
end

def do_preprocessing file
text = File.readlines(file).collect{|l| l.chomp}.join
text.gsub! /([a-zA-Z0-9])([,:.!?;])/, '\1 \2'
text.squeeze! ' '
words = text.split ' '
for i in (0..words.size-2)
# if we encounter this word first initialize with empty Hash
@word_map[words] ||= {}
@word_map[words][words[i+1]] ||= 0.0
@word_map[words][words[i+1]] += 1.0
end

# generate prob distribution for text
@word_map.keys.each do |k|
sum = @word_map[k].values.inject(&:+)
@word_map[k].keys.each{|l| @word_map[k][l] /= sum}
end
end

def generate start_word = nil
text = [start_word || @word_map.keys[rand(@word_map.keys.size-1)] ]
while !(/[.!?:;]/ === text.last) do
w = choose_next(text.last)
break if !w
text << w
end
text
end

def choose_next word
roll = rand
cand = @word_map[word]
return nil if !cand
i = 0
while roll > cand.values
roll -= cand.values
i += 1
end
cand.keys
end
end

And the inteface code which maintains a collection of text generators and
does interfacing with the output (stdout at the moment) and restriction to
140 chars etc:

# load Markov chain text generator
require 'markov_text'

class TwPerson

def initialize min, max, *files
@max = max
@min = min

@name = "Mark V. Shaney"
@pwd = "markovianSplitPersonality"

@gens = []
files.each do |f|
@gens << MarkovText.new(f)
end

@pool = []
generate_text
end

def run
loop do
make_post
time = rand(@max-@min) + @min
puts "> Made my post, sleeping for #{time}s"
sleep(time)
end
end

def make_post
puts "> Trying to post"
text = ""
while (text.length + @pool.last.length) < 139
text += " " + get_next
end
text.squeeze! ' '
text.gsub!(/( )([.,;:?!])/) do |m|
m[1]
end
do_post text
end

def generate_text
puts "> Generating new text pool"
m = @gens.shift
@pool += m.generate
@gens << m
end

def do_post txt
puts txt
end

def get_next
generate_text if @pool.size < 2
@pool.shift
end

end

This solution is quick and dirty and does not claim to be either elegant
or free from errors ;)

Thorsten

Daniel said:
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

The three rules of Ruby Quiz:

1. Please do not post any solutions or spoiler discussion for this
quiz until 48 hours have elapsed from the time this message was
sent.

2. Support Ruby Quiz by submitting ideas and responses
as often as you can!
Visit: http://rubyquiz.strd6.com/suggestions

3. Enjoy!

Suggestion: A [QUIZ] in the subject of emails about the problem
helps everyone on Ruby Talk follow the discussion. Please reply to
the original quiz message, if you can.

RSS Feed: http://rubyquiz.strd6.com/quizzes.rss

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

## Twitter Personalities (#208)

Merhaba Rubyists,

This week's quiz is to create a program that will generate messages
140 characters in length. There primary use will be to create a
Twitter "personality". At the end of the quiz period these
"personalities" will be unleashed on the internet and we'll see how
they do in the wild.

The programs will consist of two parts: a component for interacting
with Twitter, and a top secret "personality" module.

For the Twitter interface component there will be no no-spoiler
period. Please feel encouraged to discuss different libraries or
methods on the mailing list. Let's all work together to find the best
interface.

The "personality" component can take any inputs and will produce a 140
character message when called. The "personality" may remember state.
The no-spoiler period applies for the "personality" component; please
save them until everyone has had a chance to consider their own
implementations.


Have Fun!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top