Conversation started Oct 24, 2019 at 4:55.
Oct 24, 2019 04:55
@JohnRennie how would u create random sentences in python
Do you mean take real words and arrange them in a random order?
Yes
It should make sense
Can u do it using recursion
There is no simple way to do this in any but the most basic way because language is very complicated and there is no simply way to specify what makes sense.
13
Q: Computer AI algorithm to write sentences?

XeoncrossI am searching for information on algorithms to process text sentences or to follow a structure when creating sentences that are valid in a normal human language such as English. I would like to know if there are projects working in this field that I can go learn from or start using. For example...

@JohnRennie looks complicated
1
Q: python, creating a random sentence generator from dictionary

sev.def sentence_generator(filename, length=10): random.seed(1) # Set the seed for the random generator - do not remove my_tuple1 = learn(filename) sorted_word_list = sorted(my_tuple1[1]) i = 0 while True: word = random.choice(sorted_word_list) word1 = "" ...

How does this work
Give me a moment and I'll have a look.
The code in that question is only partial because it doesn't give the code for the learn() function and I'd guess that's the complicated bit.
Oct 24, 2019 05:40
@JohnRennie can u guess what the function does
@Aladdin Yes, I think so. I did a quick bit of research on this and it's quite interesting.
The idea is that you take some existing text and you analyse it to find out what words common follow other words.
Then you use that information to generate the random sentence.
can u post it
I really need help
Suppose we take some random bit of text. Give me a moment and I'll find something.
Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who was a farmer, and Aunt Em, who was the farmer's wife. Their house was small, for the lumber to build it had to be carried by wagon many miles. There were four walls, a floor and a roof, which made one room; and this room contained a rusty looking cookstove, a cupboard for the dishes, a table, three or four chairs, and the beds. Uncle Henry and Aunt Em had a big bed in one corner, and Dorothy a little bed in another corner. There was no garret at all, and no cellar – except a small hole dug in the ground, called a
For example that's from the start of the book The Wizard of Oz.
Now consider pairs of words from this text e.g. consider the two words "who was".
We can go through the text and see what word follows the two words "who was". We can build up a list of all such words.
@Aladdin OK so far?
I will come back in 1 hr. I got busy. Sorry
OK, See you later.
Oct 24, 2019 06:19
@JohnRennie yes
@Aladdin you're back?
I need 5 minutes to finish up something at work ...
Fine by me
@Aladdin hi
Oct 24, 2019 06:34
Hi
As I was saying, if you take the two words who was and look in the text for them you find:
who was a farmer
who was the farmer
So the two words "who was" can be followed by the words "a" and "the". If you're making up sentences at random and you have the words "who was" in your sentence you could randomly choose one of the two words known to follow "who was" to make your random sentence and it would probably make sense.
I get the gist
So what you do is take your sample text and for every two work sequence that occurs in the text you make a list of all the words that follow those two words.
You put all this data in a dictionary. I'm not sure if you've learned about dictionaries in Python yet?
Oct 24, 2019 06:40
I learnt
OK, so in the dictionary the key is the two word sequence and the value is a list of all the words known to follow the two words in the key.
Once you've built up your dictionary you can generate a random sequence by:
1. chose a key at random and start with those two words e.g. "who was"
2. get the list of words that follow your two words and choose a word from this list at random. So in this case you might choose "the" and now your sentence is "who was the".
3. Now take the last two words of the sentence "was the" and you use these two words as the key and find the words that follow "was the".
Keep repeating the process until you reach some predetermined sentence length.
@JohnRennie ok
I would try writing the code but in case can u write the code too
Bc I am not yet confident in dictionary
This is a longer program than any you've written so far.
With a task like this you have to break it into parts and think about each part separately.
My program is supposed to be big so this fits
@JohnRennie ok
First decide what text you are going to use for the initial analysis. Any text off the Internet will do. You can keep this text in a file and read the file from your program. That way you can change the text whenever you want by editing the file and changing the text.
So you need to know how to read text froma file in Python.
Oct 24, 2019 06:54
Ok
I would start by writing a function to read the text from the file. Get that working first before you move onto the next stage.
@JohnRennie I had a doubt
@Aladdin yes?
Will this gurantee thst sentence will make sense
It depends what you mean by make sense.
The sentences will look OK at first glance because they are built from word sequences that occur in real text. But they might be very odd.
Oct 24, 2019 07:02
Okay
To be fair this is quite a hard program for you to write.
Has it been set as a project, or something similar?
Oct 24, 2019 07:17
@JohnRennie project
@Aladdin that would make sense. It's a lot of work.
I will start with the function
Oct 24, 2019 07:44
@JohnRennie help
The zip() function returns an iterator of tuples based on the iterable object. If a single iterable is passed, zip() returns an iterator of 1-tuples. Meaning, the number of elements in each tuple is 1. ... It's because iterator stops when shortest iterable is exhaused.
what does this mean
Let me have a look at the definition of zip ...
aha k
@JohnRennie # Splitting at 3
print([word[i:i+3] for i in range(0, len(word), 3)])
how does this work
word = 'CatBatSatFatOr'
The loop for i in range(0, len(word), 3 takes values of i starting at zero and increasing in steps of 3 up to len(word)-1. So the values of i will be 0, 3, 6, 9 etc up to the length of the list word minus one.
And word[i:i+3] takes the three characters from the string starting at i. So if i=0 it will take word[0] + word[1]+word[2] or if i=3 it will take word[3] + word[4]+word[5].
So if you look at your string word = 'CatBatSatFatOr' it's going to be split up into three letter groups.
OK so far?
Oct 24, 2019 07:56
ok
The command:
[word[i:i+3] for i in range(0, len(word), 3)]
is a special way of initialised a list. It takes the string word, splits it into three letter words and creates a list from those words.
>>> word = 'CatBatSatFatOr'
>>> [word[i:i+3] for i in range(0, len(word), 3)]
['Cat', 'Bat', 'Sat', 'Fat', 'Or']
@JohnRennie word = 'geeks, for, geeks, pawan'

# maxsplit: 0
print(word.split(', ', 0))

# maxsplit: 4
print(word.split(', ', 4))

# maxsplit: 1
print(word.split(', ', 1))
['geeks, for, geeks, pawan']
['geeks', 'for', 'geeks', 'pawan']
['geeks', 'for, geeks, pawan']
The split function takes a string and splits it into a list of strings using the character you specify.
So for example:
>>> word = 'geeks, for, geeks, pawan'
>>> word.split(',')
['geeks', ' for', ' geeks', ' pawan']
splits the string at the three commas to produce a list of four strings.
Oct 24, 2019 08:12
There is an optional second argument that specifies how many times the string is split. The default is to split the string at every occurrence of the split character.
didn't understand
@Aladdin word.split(',') splits at every comma. There are three commas so it produces four strings after the split. OK so far?
ok
@JohnRennie I created the function.would u like to check after discussion
If instead we do word.split(',', 1) this only splits once. So our original string 'geeks, for, geeks, pawan' is split into two string 'geeks and ' for, geeks, pawan'.
let me try
@JohnRennie Why comma
Oct 24, 2019 08:27
Do you mean why choose a comma to use for splitting?
lol
i messed up
@JohnRennie a='Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who

was a farmer, and Aunt Em, who was the farmer's wife. Their house was small, for

the lumber to build it had to be carried by wagon many miles. There were four

walls, a floor and a roof, which made one room; and this room contained a rusty

looking cookstove, a cupboard for the dishes, a table, three or four chairs, and

the beds. Uncle Henry and Aunt Em had a big bed in one corner, and Dorothy a little
is this okay?
it's wrong i guess
Can I suggest a different approach?
Take a really simple string as a test: "the cat sat on the mat"
We want to find the words that follow a pair of words.
The first pair of words is "the cat" and the word that follows is "sat", so we want to add an entry to our dictionary:
"the cat": "sat"
Oct 24, 2019 08:35
That is, when we look up the word pair "the cat" in the dictionary it tells us that the word "sat" can follow the word pair "the cat".
Now we need to look at the next word pair and this is "cat sat" i.e. we move along one word. Now the word that follows is "on". So our dictionary now looks like:
"the cat": "sat"
"cat sat": "on"
Then for the next pair we move on one step so the pair is "sat on" and the next word is "the"
"the cat": "sat"
"cat sat": "on"
"sat on": "the"
And so on. The idea is that for every word pair in the sentence our dictionary tells us what the next word is.
Give me a moment to wrte some code.
>>> a = "the cat sat on the mat"
>>> b = a.split(" ")
>>> b
['the', 'cat', 'sat', 'on', 'the', 'mat']
The way I would do this is to start by splitting the string at spaces to give a list of the individual words in the string. OK so far?
Now we go through the string a word at a time to see what word follows the pairs:
>>> for i in range(0,len(b)-2):
...   print(b[i] + " " + b[i+1] + ": " + b[i+2])
...
the cat: sat
cat sat: on
sat on: the
on the: mat
Can you see how this works?
Oct 24, 2019 08:50
The idea is that for any pair of words we can look in our dictionary to find out what word follows that pair of words.
So you'd do something like:
>>> worddict = {}
>>> for i in range(0,len(b)-2):
... key = b[i] + " " + b[i+1]
... worddict[key] = b[i+2]
...
>>> worddict
{'the cat': 'sat', 'cat sat': 'on', 'sat on': 'the', 'on the': 'mat'}
Now suppose want to find what word can follow, for example, "sat on" we use:
wait
>>> worddict["sat on"]
'the'
ok
so after all this
how will u combine it into sentences
Oct 24, 2019 08:55
I would ask the user to enter a word pair. Suppose the user enters "the cat", so our sentence starts with "the cat".
Now we look in the dictionary and we find the word following "the cat" is "sat". We append this to our sentence so now we have "the cat sat".
Now we take the last two words of our sentence i.e. "cat sat" and we look up this pair in the dictionary and we find "on". Append this and now our sentence is "the cat sat on".
okay i understand how this is going
And we keep going i.e. we keeping taking the last pair of words and finding the word that follows them.
so we will go till the len of dictionary
Oct 24, 2019 08:58
Well we need to have some way of deciding when we reach the end of a sentence.
There are various ways you could do this. You could stop if you fail to find a match, or you could stop after a set number of words.
Or there are more cunning things you could do.
e.g. in real texts sentences stop at a full stop or a question mark or an exclamation mark etc.
e.g. a = "the cat sat on the mat."
And you could stop your sentence when you come to a word that ends in a full stop etc.
 
1 hour later…
Oct 24, 2019 10:10
@JohnRennie >> a = "the cat sat on the mat"
>>> b = a.split(" ")
>>> b
['the', 'cat', 'sat', 'on', 'the', 'mat']
The way I would do this is to start by splitting the string at spaces to give a list of the individual words in the string. OK so far?
Now we go through the string a word at a time to see what word follows the pairs:
>>> for i in range(0,len(b)-2):
... print(b[i] + " " + b[i+1] + ": " + b[i+2])
...
the cat: sat
cat sat: on
sat on: the
on the: mat
I didn't understand what u did here
You mean for i in range(0,len(b)-2):?
Yep that line
And next code lines
The list b contains:
b[0] = 'the'
b[1] = 'cat'
b[2] = 'sat'
b[3] = 'on'
b[4] = 'the'
b[5] = 'mat'
Yes?
What I want to know is for all the pairs of words in the list what word is next.
The first pair is b[0],b[1] i.e. 'the cat' and the word that follows is b[2] = 'sat'. Yes?
Oct 24, 2019 10:17
yes
The second pair is b[1],b[2] i.e. 'cat sat' and the word that follows is b[3] = 'on'.
The third pair is b[2],b[3] i.e. 'sat on' and the word that follows is b[4] = 'the'.
@JohnRennie can we stop for a minute
let me post my function
@JohnRennie c="my name is percy jackson"
def text_reader(x):
	a=x.split()[0::2]
	b=x.split()[1::2]

	d=list(zip(a,b))
	print(d)

text_reader(c)
This is what i have written till now
this is my function
can you explain using this example what you are doing
it doesn't include jackson....
@Aladdin explain what I am doing? Do you mean explain why this code doesn't work?
Oct 24, 2019 10:22
OK, so in the dictionary the key is the two word sequence and the value is a list of all the words known to follow the two words in the key.
Once you've built up your dictionary you can generate a random sequence by:

1. chose a key at random and start with those two words e.g. "who was"
2. get the list of words that follow your two words and choose a word from this list at random. So in this case you might choose "the" and now your sentence is "who was the".
3. Now take the last two words of the sentence "was the" and you use these two words as the key and find the words that follow "was t
so how am i going to fill my dictionary
i don't understand this
the pragraph has lots of sentences
which sentence to choose
Hang on, what exactly are you asking? The text above assumes that all the processing of pairs has been done. Aren't we still wondering how to process the word pairs?
no i got the processing pairs
@JohnRennie a = "the cat sat on the mat"
>>> b = a.split(" ")
>>> b
['the', 'cat', 'sat', 'on', 'the', 'mat']
u started with a sentence
why did u choose this
sentence
there will be other sentences in the paragraph
I just chose some random text. In the real program I'd have a large amount of text that I'd read from a file. You want a lot of text so you have lots of different pairs of words to work with.
I chose that text because it was short enough that I could work through it to show how the dictionary is constructed.
but we don't know the sentences right.We only got the pairs
I don't understand what you're asking.
Oct 24, 2019 10:32
@JohnRennie Okay ignore me
i got what you said
OK :-)
@JohnRennie for i in range(0,len(b)-2):
why len(b)-2)
Because we are looking at groups of three words i.e. a pair and the word that follows.
If we try to look at the last word in the list then the code would crash because b[i+1] and b[i+2] would be past the end of the list.
aha
okay
Oct 24, 2019 10:47
c="my name is percy jackson.I am not the lightning theif."
def text_reader(x):
	a=x.split()
	worddict={}
	for i in range(0,len(a)-2):
		key=a[i]+" "+a[i+1]
		worddict[key]=a[i+2]
	print(worddict)

text_reader(c)
is this correct
can you see the output and tell me
it looks kinda messed up...like the key with full stop
how do i improvise it
Let me run the code ...
You need to put a space after the first full stop so the text can be split there:
c="my name is percy jackson. I am not the lightning thief."
This gives me:
D:\rhs\Python>python test.py
{'my name': 'is', 'name is': 'percy', 'is percy': 'jackson.', 'percy jackson.': 'I', 'jackson. I': 'am', 'I am': 'not', 'am not': 'the', 'not the': 'lightning', 'the lightning': 'thief.'}
And that looks pretty good.
I agree that you probably don't want full stops in the dictionary key, but it will be useful to keep the full stops in the dictionary values.
The reason is that if you pull a word with a full stop out of the dictionary you can take this to mean your random sentence ends at that word.
okay
so i can exclude it
@JohnRennie what i was thinking of is
using random module to pick out any key from dictionary
except for those with the full stops
and then somehow add the consecutive letters
I would do this:
c="my name is percy jackson. I am not the lightning thief."
def text_reader(x):
	a=x.split()
	worddict={}
	for i in range(0,len(a)-2):
		key=a[i].replace('.', '') + " " + a[i+1].replace('.', '')
		worddict[key]=a[i+2]
	print(worddict)

text_reader(c)
So you remove the full stops from the keys but leave them in the values.
This gives me:
D:\rhs\Python>python test.py
{'my name': 'is', 'name is': 'percy', 'is percy': 'jackson.', 'percy jackson': 'I', 'jackson I': 'am', 'I am': 'not', 'am not': 'the', 'not the': 'lightning', 'the lightning': 'thief.'}
I guess ignoring the full stops does give you some weird pairs e.g. 'jackson I': 'am'
You make a good point. You should probably not use words in a key if they have a full stop.
Oct 24, 2019 10:59
yeah
c="my name is percy jackson. I am not the lightning thief."
def text_reader(x):
	a=x.split()
	worddict={}
	for i in range(0,len(a)-2):
		if a[i].find('.') == -1 and a[i+1].find('.') == -1:
			key=a[i] + " " + a[i+1]
			worddict[key]=a[i+2]
	print(worddict)

text_reader(c)
aha this looks good
Can I make one more suggestion?
sure
Suppose your two words are "the dog". There will be lots of words in your learning text that follow this e.g. "the dog sat", "the dog barked", "the dog rat", and so on.
Oct 24, 2019 11:06
ok
And you want your dictionary entry for "the dog" to keep all these words as a list. i.e. the entry will look like:
"the dog": ["sat", "barked", "ran"]
Then when you are constructing a sentence you can randomly choose one of the words from the list.
Shall I show you the code I used for this?
yes
but what if the word comes only once
That's OK. You can have a list with one word in it. Then the random choice will always return that one word.
Anyhow, this is what I did. You'll see it's very similar to your code but with a few tweaks to make the value a list:
for i in range(len(wordlist)-2):
    if wordlist[i].find('.') == -1 and wordlist[i+1].find('.') == -1:
        key = wordlist[i] + ' ' + wordlist[i+1]
        if WordPairs.get(key) is None:
            WordPairs[key] = [wordlist[i+2]]
        else:
            WordPairs[key].append(wordlist[i+2])
how does get(key)work
Suppose our pair is "the dog", and the following word is "sat".
If the key "the dog" doesn't exist in the dictionary we have to create that key with the value "sat".
Oct 24, 2019 11:13
yes
But if the key does exist then we want to append our word "sat" to the list of words that is already in that key.
If you call WordPairs.get(key) this looks to see if the key key is already in the dictionary. If the key is not there it returns None.
So we can use this to see if our key already exists or not.
So look at the lines:
    if WordPairs.get(key) is None:
        WordPairs[key] = [wordlist[i+2]]
Oct 24, 2019 11:17
@JohnRennie this work only for dictionary right
You're pushing at the boundaries of my knowledge of Python now.
aha ok
The get() method exists for dictionaries, but I don't know whether or not similar methods exist for other types of variable.
lemme search it up
I guess probably not.
Oct 24, 2019 11:19
yes you are right
I've been playing with this, and if you're interested I have the text of The Wizard of Oz in a form that you can use with your program. If you would like a copy of it I can put it on my website for you to download.
@JohnRennie yes
Open that page then right click on sentences.txt and choose Save as then save it into the same folder as your program.
done
@JohnRennie
Will python accept such a long string
The way I would read the data is like this:
# Define the name we use for the file containing the learning text
TEXTFILE = "sentences.txt"

# Function to read the text
def readdata():
    with open(TEXTFILE) as f:
        contents = f.read()
    return contents

# Main program
text = readdata()

# Build the dictionary of word pairs
builddictionary(text)
I don't know if you've done reading stuff from files yet.
I must admit I just Googled for how to read text from a file :-)
Oct 24, 2019 11:34
don't know if you've done reading stuff from files yet.
i dont understand
i copied the text
Well you have the text I sent in the file sentences.txt. Yes?
And you need that text to be in a variable in your program.
So you need your program to open that file, read the text from it and store the text in a variable.
Oct 24, 2019 11:36
use module
module?
ignore me
Oh you mean put a = 'exceedingly long string......' in a module?
yes
and run that module
import it
Well you could do, but why bother.
Oct 24, 2019 11:38
so wht else can i do
You can just read the text straight from the file.
That's what my function readdata() does.
def readdata():
    with open(TEXTFILE) as f:
        contents = f.read()
    return contents
how does this work
The function open() takes a file name and it opens that file. It returns an object called a descriptor that you use to do the reading.
Actually let me simply the function:
def readdata():
    f = open(TEXTFILE)
    contents = f.read()
    return contents
The first line in the function opens the file with the name held in the variable TEXTFILE
Oct 24, 2019 11:43
ok
This returns a descriptor that I store in the variable f.
Then the method f.read() reads everything in the file and returns it as a string.
okay
So the second line contents = f.read() sets the variable contents to the text that was in the file.
aha
so this will allow us to read long strings
Oct 24, 2019 11:46
feels like today we did some high level stuffs
This is an interesting project. It needs a lots of stuff!
So you've basically done reading in the source text and constructing the dictionary. You just need to write a function that builds a random sentence using the contents of the dictionary.
yep that i can do that
I need to go now, but I'll be back later if you want to discuss how to build the sentence.
The way I did it was to ask the user to type the first two words of the sentence.
e.g. the user might type "the dog"
Then I use those words as the key and build the sentence from there.
For example my code gives sentences like this:
D:\rhs\Python>python sentences.py
Enter two words to start the sentence.
First word: the
Second word: dog
The dog and the tin woodman came to another tree, as he spoke there came a day longer, said the princess.
Oct 24, 2019 11:54
wow
it looks quite nice
You get some really weird sentences :-)
D:\rhs\Python>python sentences.py
Enter two words to start the sentence.
First word: the
Second word: dog
the dog in her had dried up many years older.
 
Conversation ended Oct 24, 2019 at 11:55.