Python character search in list - python

I've got a txt which first line include the good answers of a test, and the other lines include the ID of the participants and they answers (' ' between). If the user give an input (call it n) its means the number of the question, and I have to count how many of them are good (similar which is in the [0] line n's)
The txt's like:
BCCCDBBBBCDAAA
AB123 BXCDBBACACADBC
AD995 BABCDABCBCBBBA
AH97 BCACDBDDBCBBCA
AK260 DCDCBDDAACDBDB
AL580 AACCDBBCDCAACA
AN562 BAABBDCACCBDBB
And my code is:
person=[]
with open('answers.txt', 'r') as v:
pcs=sum(1 for line in open('answers.txt'))
for i in range(0, pcs):
person.extend(v.read().strip().split())
result=0
jnum=input('which exesises result are you interested in? ')
jnum=int(jnum)
good=person[0]
good=good[jnum]
for i in range(0, pcs):
letter=person[i*2]
letter=letter[jnum]
if good==letter:
result+=1
print(result)
else:
result=result

Yes, it will freeze, once you fix enough problems to get that far: your final two lines are an infinite loop. You don't change either good or letter within the loop -- as soon as they match, you're stuck inside.
Insert print statements to trace your execution and data values.
Also, I strongly recommend that you adopt incremental programming. Your code has multiple problems; you should write just a few lines, make sure that they work, and then go on to the next small group.

Related

Print prints one space too much

I was currently finishing up my project that concerned ciphering a sentence using a key matrix.
As of now, all the calculations are done and correct, the only thing left is for me to print the output to the screen and voila.
What you can see above is my current output.
The Key matrix is printed just how I want it to be printed and all is good with Encrypted message as well, except that my print prints one space more than what is needed. This is quite problematic because of the fact that the project is going to be verified with a bot, so even though it changes nothing on the screen (except when piping into cat -e) the bot is still going to pick it up.
My print function looks like the following:
def the_output_printer(key_matrix, encrypted_matrix, matrix_size):
length = (len(sys.argv[1]));
if (length == 0):
exit(84);
lines = round(length / matrix_size, 0);
if (length % matrix_size != 0):
lines += 1
lines = int(lines);
print("Key matrix:");
for line_index_key in range(0, matrix_size):
for col_index_key in range(0, matrix_size):
if (col_index_key != matrix_size - 1):
print("{}".format(key_matrix[line_index_key][col_index_key]), end="\t");
if (col_index_key == matrix_size - 1):
print("{}".format(key_matrix[line_index_key][col_index_key]), end="\n");
print("\n", end="");
print("Encrypted message:")
for line_index in range(0, lines):
for col_index in range(0, matrix_size):
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
print();
I tried something simillar to what I've done for Key Matrix but it didn't really work out.
Any ideas as how to not print that last " "?
Thank you all for reading!
As I'm still new to python please excuse my horrible coding style, I'm still working on it.
Your problem is that each iteration of your nested for loop prints your end argument, one space. That's fine assuming you want one between all elements, but it doesn't know to skip it on the last iteration of the nested loop.
There's more than one way to solve this, but because you mentioned being new to Python I'll stick to a simple one - instead of printing each number, collect up the numbers in a single list and then pass that list to print(). print() defaults to adding a separator between its arguments but not after the final one.
message_elements = []
for line_index in range(0, lines):
for col_index in range(0, matrix_size):
message_elements.add("{}".format(encrypted_matrix[line_index][col_index]))
print(*message_elements)
The * operator in the final print() unpacks the list, as if you'd specified each of its elements as an argument to print(). It's equivalent to:
print(message_elements[0], message_elements[1], ...)
Once you're more experienced with Python there are ways to more concisely collect up the matrix elements into a list, or to avoid an intermediate list at all and use a single expression to do it. But this should work and changes as little as I can from your existing code.
Alright, I figured it out :)!
The problem was that as I'm still new to Python, I once again messed up how
range() functioned.
My previous attempt at fixing this resembled:
if (line_index == lines and col_index == matrix_size):
print("{}".format(encrypted_matrix[line_index][col_index]));
else:
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
I ommited the fact that while using
in range(foo)
the value stops at foo - 1, or quite simply while it is strictly inferior to foo.
The fix was quite simply to add -1 to my if statement, EXACTLY the same thing I forgot when i was doing my key_matrix printing part. The fixed part of the function now looks lice this:
if (line_index == lines - 1 and col_index == matrix_size - 1):
print("{}".format(encrypted_matrix[line_index][col_index]));
else:
print("{}".format(encrypted_matrix[line_index][col_index]), end=" ");
Which gives me the correct output :). Thank you everyone but I figured it out after re-reading the code few times.

Order of array items changing when being printed

I was writing a Python program which includes printing a array created from user input in the order the user inputed each item of the array. Unfortunately, I have had few problems with that; Once it repeated the first item twice with one of the set, and then in another set it put the last 2 items at the beginning.
I checked the array in the shell and the array contained the right amount of items in the right order, so I don't know what is going on. My script looks something like this:
i = 1
lines = []
for i in range (1, (leng + 1)):
lines.append(input())
input() # The data stripped is not used, the input is a wait for the user to be ready.
i = 0
for i in range (0, (leng + 1)):
print(lines[i - len(lines)])
I searches found me nothing for my purposes (but then again, I could have not used the correct search term like in my last question).
Please answer or find a duplicate if existing. I'd like an answer.
Don't you just want this?
for line in lines:
print(line)
EDIT
As an explanation of what's wrong with your code... you're looping one too many times (leng+1 instead of leng). Then you're using i - len(lines), which should probably be okay but is just the equivalent of i. Another fix for your code could be:
for i in range(len(lines)):
print(lines[i])
SECOND EDIT
Rewriting your full code to what I think is the simplest, most idiomatic version:
# store leng lines
lines = [input() for _ in range(leng)]
# wait for user to be ready
input()
# print all the lines
for line in lines:
print(line)

Anagram generator from input in Python malfunction

I tried to code a simple generator of a list of anagrams from an input. But after I rewrote the code it gives me only 2 outputs. Here's the code
import random
item=input("Name? ")
a=''
b=''
oo=0
while oo<=(len(item)*len(item)):
a=''.join([str(y) for y in random.sample(item, len(item))]) #this line was found on this site
b=''.join([str(w) for w in random.sample(item, len(item))]) #because in no way i had success in doing it by myself
j=[]
j.append(a) #During the loop it should add the anagrams generated
j.append(b) #everytime the loop repeats itself
oo=oo+1
j=list(set(j)) #To cancel duplicates
h=len(j)
f=0
while f<=(h-1):
print(j[f])
But the output it gives is only one anagram repeated for ever.
As far as I can see you don't increment f at the end.
Do it rather like:
for item in j:
print( item )
The other thing is, you overwrite j in every loop. Are you sure you wanted it like that?
There were several problems with your loop construct, including reinitializing your results every time. Try a simpler approach where things are already the type they want to be rather than constantly converting. And not everything you want to do requires a loop:
import random
item = input("Name? ")
length = len(item)
anagrams = set()
for repetitions in range(length**2):
anagrams.add(''.join(random.sample(item, length)))
print("\n".join(anagrams))
However, these anagrams are not exhaustive (the random nature of this means some will be missed.) And they're not really anagrams as there's no dictionary to help generate actual words, just random letters.

python small crosswords for beginners

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.

Printing 5 numbers in a row

I have to write a program to print the numbers 1 to 50, but with 5 numbers in a row, like:
1,2,3,4,5
6,7,8,9,10
like that till 50 without using lists
for i in range(2,51):
if i%5==0:
print i
this is giving me 5,10,15,20
Please help me
A few hints:
The first parameter for the range() function is incorrect. It must be 1 not 2. The start index included, the ending one is excluded. This is btw a very good practice to avoid bugs.
With the modulo operator you found a way of detecting every 5 values; you could use this to print a line when that happens. You then would be left with having to find a way to not output a line when you output one value at at time; look in the python documentation for way to make the print() function do this. (attention, things have changed in the area of print with Python 3.0, but you seem to be using a 2.x version given your example)
An alternative approach is to use the 3rd argument of the range() function, to step though the sequence, in increments of 5). Such a range would give you 1, 6, 11, 16 etc. in sequence, and you can use this number as the first of each line, and simple addition for the following ones.
You can start almost like you did (except you need to start from 1 - that 2 is really weird!-):
for i in range(1,51):
if i % 5 == 0:
print i
but then you need to segue into an else clause for that if, because you do want to print something even when i is not a multiple of 5 -- just something different from the simple print i you're already doing when i is a multiple of 5...:
else:
print i, ',',
As other answers already said, the trailing comma means "no newline yet"!-) ((It's plainer and more sensible in Python 3.whatever, but you're clearly using Python 2.something, and in those versions this is what you need to do)).
I've never used Python, but this should be close if not right.
for i in range(1,51):
print i;
print ",";
if (i%5==0)
{ print "\n";}
Also, remember that using print will cause a new line to start. Unless as noted above a comma is used afterwards.
You can collect values using a string for printing out later.
Some Hints
To print 1 to 50, you need to pass n+1 for eg, 1 to 51 in range function, its (i=1;i<51,i++) in C alike syntax
print comma if you want between every digits
to print line break for every 5, you can just use current if i%5==0: but print blank line, instead of i
To concatenate num + string "," you can use `i` or str(i) , you can do like `i` +","
If you dont need comma in the end, you could do like i%5 print "," else print "\n" =>
(i%5 and "," or "\n")
print i will print i line by line, and print i, will print in the same line
just my 2 cents
for i in range(1,51):
if i%5 == 0:
print i
else:
print i, ",",
(there used to be python code here)
EDIT: My apologies, didn't realize this was homework. I reeeally need to check tags before answering. Here's an explanation of what needs to happen.
Obviously you know that you're trying to output consecutive numbers from 1 to 50, so you'll need a counter. You've figured out that it'll require a range() call, but it needs to be from 1 to 51, not from 2 to 50.
The reason the range() call needs to be from 1 to 51 is this: it will start the variable i at 1, then check to see if it has reached its goal (51) before looping. If the goal is reached (meaning if i == 51) it will quit the loop without executing the loop's code. So rather than go from 1 to 50, you go from 1 to 51 so that we don't skip the 50th iteration.
Next, you're going to want to have the numbers appear on-screen. But using python's print command prints each number on a new line! That's obviously not what you want. So you're going to have to create a buffer string to append each number to until you're ready to print the line. You can call it 'output' or whatever.
Personally, I like to clear the buffer BEFORE the for loop just to be sure no residual memory traces find their way into the output. Call me paranoid. So I write output = "" on a line before the loop.
Now you've got a buffer string, all you need to do is follow a logical flow:
Add i to the buffer output.
If i is a multiple of 5, print the buffer output and reset it back to an empty string. (We do this so that we can start the buffer for the next line.)
If i is NOT a multiple of 5, add a comma to the output buffer, so that the next number added will be after the comma.
Continue our loop.
These steps should be pretty simple to figure out. Step 2 you've already seen before... To check if a number is a multiple of another number, simply use %. If A % B == 0 then A is a multiple of B.
This should be a pretty straightforward explanation for how to solve this problem. Hope it helps.
And sorry for ruining your learning experience by posting the answer! Now you'll understand why the answer works.
for i in range(1,51):
if i%5 != 0:
print str(i)+',' , # trailing comma means no \n
else:
print i
this code will give you the required output.
#python
for i in range(1,51):
if i%5 == 0:
print (i)#this will give \n at the end
else:
print (i,end=",")#this will print the numbers with coma at the end
you can put 'end="" ' to print without a space
for space 'end=" "'
In one statement, you can unpack a generator expression withing print and utilise the sep argument. The benefit of this solution is there's no need for explicit if / else conditional logic.
k, n = 5, 50
print(*(','.join(map(str, range(i, i+k))) for i in range(1, n+1, k)), sep='\n')
# 1,2,3,4,5
# 6,7,8,9,10
# 11,12,13,14,15
# 16,17,18,19,20
# 21,22,23,24,25
# 26,27,28,29,30
# 31,32,33,34,35
# 36,37,38,39,40
# 41,42,43,44,45
# 46,47,48,49,50

Categories