python small crosswords for beginners - python

my_str="ellezagchickenbndodetballigatoraaaolmeznacattleeblrctacfenarcesssadlritfhftrarrssos aoiarefaareppohssarghcerumrheirmmwildfcumeboimltaairfovindalbiglalobehoeasiaxuesabldinbbccrhhrtylrlahsifdlogkrctlaiareogoldfinchefnnddmneepoletnarntadodinosauroxofoeclictnahpelepalgaierhohcaorkcocyatrmoacrflamingoerefafloechateehchdracaribou"
def create_2d_list(N):
output_list=[]
counter=0
for row in range(0,N):
temp=[]
for col in range(0,N):
temp.append(my_str[counter])#you can add a charcter instead of counter
counter=counter+1
output_list.append(temp[:])
return output_list
N=18
x=create_2d_list(N)
for row in range(0,N):
total=0
s="|"
for col in range(0,N):
my_str="{0:2} ".format(x[row][col])
s=s+my_str+"|"
print "-"*(N*4+1)
print s,
print " "
the_valid_words=open("E:/asd/words.txt","r").readlines()
def looking_word_left_to_right(the_list):
for any_words in the_valid_words:
for every in x[0]:
the_first_index=x[0].index(every)
for every in range(the_first_index,(the_first_index)+7):
c=str(every)
the_join=" ".join(c)
if the_join==the_valid_words:
word.upper().replace(every,x[0].upper(every))
return x[0]
print looking_word_left_to_right(x)
every time i run the program, the looking_word_left_to_right doesn't print anything
P.S its similar to small crossword for beginners, Capitalizing the letters that make a word and removing every other letter without changing places, if someone could give like thoughts on how to proceed that would be great. i have certain valid words to look for.
and i'm a newbie so go easy on me :)
appreciate the help.

There seem to be a number of problems.
Why are you operating on x when you also pass it in as the_list" Just use the_list.
You're only looking at the first line of x and never moving beyond that.
It looks like you're putting a space between every character before you compare. If c = "abcdefg" then " ".join(c) will give you "a b c d e f g". If your the_valid_words doesn't have spaces in it, then if the_join==the_valid_words will always evaluate to false.
You're comparing to the_valid_words, which is your entire list. You should probably be comparing to EACH valid word using any_word... which you aren't using anywhere else.
You may also be running into a problem with iterating over x, while you're changing it (it will sometimes invalidate the iterator... but sometimes not). I.e. if you're iterating through x and then you change x before you're done iterating, then Python might not know where the iterator belongs in the new version of x. Since the_list is the same as x anyway, it might be better to do for every in the_list: and then change x to your heart's content.
It looks like you may not quite understand how for loops work in Python. Take a look at those, and that may help some.

Related

Should I use a for statement here or not?

I have this question and I want your expert answers about it, because I want to get better in programming.
"""
The parameter s_str is a string. The parameter n is an int > 0.
The function x() should return the last n characters of s_str if
s_str has a length >= n, or the empty string if s_str has a length < n
Example:
x('abcdef', 3) == 'def'
"""
So, I could build the exact code with or without the for statement and it would give me (print) the same values, but I don't know what is the more common way to do it. If I'd go for a for statement, I'd do this:
for i in s_str:
if len(s_str) >= n:
return a_str[-n:]
elif len(s_str) < n:
return ''
Is the idea of using a for statement wrong if you know in advance that you are not going to use i, in this case? I could easily remove the for statement and still get the right answer, so is that enough reason not to use it?
There are cases in which a for loop is justified even if you do not intend to use the loop index (e.g when you want to preform a certain task n times). Having said that, this problem can be solved in a more elegant way, as you have shown.
Also please note that your code iterates over the string len(str) times, except it returns in the first iteration, so the for loop in this case is redundant.
"so is that enough reason not to use it?"
Yes. Simple is better than complex.
You dont actually need a for loop
if len(a_str) >= n:
return a_str[-n:]
it is better and simple too.

Python 3 Error Missunderstanding (IndexError)

Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)

How to properly iterate through a for loop with python

I am relatively inexperienced and come from c#. I am attempting to iterate through a string and individually print out each letter using a for loop.
In c# this would (if I remember correctly) be written like so:
string x = test;
foreach(i in x)
{
print(x[i]);
}
But in python, when I type
x = "test"
for i in x:
print(x[i])
The python shell tells me that i must be an integer.
I am actually pretty sure that my syntax is incorrect in my c# example, but to get to the question:
How would i properly iterate through a string using a for, or foreach loop in Python?
I have been searching the web and am somehow coming up empty handed. Sorry if this is a foolish inquiry.
Your variable x is a string type, therefore, when you type x[i] you are going to get the letter at the position i.
However, in your loop, you have something different:
x = "test"
for i in x:
print(x[i])
This for loop (for i in x) means: for each letter i in the string x, do the following. So, your i variable is actually a letter, not an integer.
So, to print every letter of the string x, just use print(i):
x = "test"
for i in x:
print(i)
But, if you really want your i to be an integer, instead of for i in x, use for i in range(0, len(x)). And in this case, you would have to access the letter by using what you originally wrote (x[i]).
x = "test"
for i in range(0, len(x)):
print(x[i])
If you really want a loop index for some reason, you can use enumerate:
x = 'test'
for i, c in enumerate(x):
print(i, x[i], c)
This took me a bit to understand as well, but I think I understand the misunderstanding. The i in for i in x already refers to the character, not the index. For example, writing
stringx='hello world
for i in stringx:
print stringx[i]
is the same as writing
print stringx['h']

Splitting a python list into multiple lists

for example, if i have a list like:
one = [1,2,3]
what function or method can i use to split each element into their own separate list like:
one = [1]
RANDOM_DYNAMIC_NAME = [2]
RANDOM_DYNAMIC_NAME_AGAIN = [3]
and at any given time, the unsplit list called one may have more than 1 element, its dynamic, and this algorithm is needed for a hangman game i am coding as self-given homework.
the algorithm is needed to complete this example purpose:
pick a word: mississippi
guess a letter: s
['_','_','s','s','_','s','s','_','_','_','_']
Here is my code:
http://pastebin.com/gcCZv67D
Looking at your code, if the part you're trying to solve is the comments in lines 24-26, you definitely don't need dynamically-created variables for that at all, and in fact I can't even imagine how they could help you.
You've got this:
enum = [i for i,x in enumerate(letterlist) if x == word]
The names of your variables are very confusing—something called word is the guessed letter, while you've got a different variable letterguess that's something else, and then a variable called letter that's the whole word… But I think I get what you're aiming for.
enum is a list of all of the indices of word within letterlist. For example, if letterlist is 'letter' and word is t, it will be [2, 3].
Then you do this:
bracketstrip = (str(w) for w in enum)
So now bracketstrip is ['2', '3']. I'm not sure why you want that.
z = int(''.join(bracketstrip))
And ''.join(bracketstrip) is '23', so z is 23.
letterguess[z] = word
And now you get an IndexError, because you're trying to set letterguess[23] instead of setting letterguess[2] and letterguess[3].
Here's what I think you want to replace that with:
enum = [i for i,x in enumerate(letterlist) if x == word]
for i in enum:
letterguess[i] = word
A few hints about some other parts of your code:
You've got a few places where you do things like this:
letterlist = []
for eachcharacter in letter:
letterlist.append(eachcharacter)
This is the same as letterlist = list(letter). But really, you don't need that list at all. The only thing you do with that is for i, x in enumerate(letterlist), and you could have done the exact same thing with letter in the first place. You're generally making things much harder for yourself than you have to. Make sure you actually understand why you've written each line of code.
"Because I couldn't get it to work any other way" isn't a reason—what were you trying to get to work? Why did you think you needed a list of letters? Nobody can keep all of those decisions in their head at once. The more skill you have, the more of your code will be so obvious to you that it doesn't need comments, but you'll never get to the point where you don't need any. When you're just starting out, every time you figure out how to do something, add a comment reminding yourself what you were trying to do, and why it works. You can always remove comments later; you can never get back comments that you didn't write.
for question one ,just list comprehension is good . it will return each element as a separate list
[ [x,] for x in one ]
As for a literal answer to your question, here's how you do it, though I can't immagine why you would want to to this. Generally, dynamic variable names are poor design. You probably just want a single list, or list of lists.
import random
for x in one:
name = 'x' + str(random.getrandbits(10))
globals()[name] = [x]

Most straightforward alternative to a while loop in python

The general point of the program is to search for words and make sure that they occur in the right order.
I am currently using the code
while not corpus[index_F2-1] == corpus[index_B]:
index_F2 = corpus.index(corpus[index_F2], index_F2+1)
in order to search for a word, check to make sure that a given word appears before it, and find a different instance of the same word in the corpus if the word does not appear in the correct environment. The only problem with this code is that, if the conditions are never met, it returns an error. Rather than having it return an error, it would be better if it could exit the loop, and then assign a new value to "F2" in order to try again. The obvious way to make the program exit the loop would be to use a while loop, but I am unsure how to get a while loop to not find a new value for F2 if the current one works. In short, it would work best if the script ran in this order.
Check to see if the current F2 will ever work
If it will not work, assign a new value to F2.
Check again recurse and check to see if the new F2 will work
and so on
An if statement would probably be in order, but exactly where and how it would work, I am unsure. Also, the code for reassigning F2 already exists. It is
index_E2= corpus.index(corpus[index_E2], index_E2+1)
index_F = index_E2+1
index_F2 = corpus.index(corpus[index_F], index_F+1)
A future problem that could present itself is that the corpus may run out of F2 values ( as a result of running out of E2 values) and display a similar error, but that is another issue.
I think I might understand what you're looking for. It sounds like you want to have multiple nested loops, with an exit point within the innermost loop. The most obvious way to achieve this, in my mind, is to enclose the loops within a function. Since all this corpus stuff is confusing, I'll use a simple example:
words_to_find = ['tree', 'cow', 'lots_of_other_words']
words_to_search = ['bathtub', 'more_words']
def find_words(words_to_search, words_to_find):
for i, fword in enumerate(words_to_find):
for j, sword in enumerate(words_to_search):
if fword == sword:
return (fword, i, j)
You can nest as many loops as you like here -- for, while, whatever -- and still break out of all of them easily once you've found what you want.
Let me know if that doesn't answer your question.
EDIT: I suppose if you wanted to have it all in one while loop you could do this:
word_list = ['blah', 'blah2', 'etc']
word_list2 = ['other', 'words']
i = 0
j = 0
while True:
if i == len(word_list):
i = 0
j += 1
elif thing_I_want(word_list[i], word_list2[j]):
do_something()
break
else:
i += 1

Categories