Why won't the loop function as intended? Details below: - python

I have asked a similar question before, but here's a slightly different problem I'm encountering after fixing some previous issues:
There are two txt files that are structured similarly into columns. File 1 has the following columns: tagname1, aapos, synonymous; and file 2 has the following: tagname2, aapos1, aapos2. What I want to do is compare every single tagname1 in file 1 to every single tagname2 in file 2 and see if they match. For every single match, I want the program to then check if the aapos value corresponding to that specific tagname1 falls betweeen aapos1 and aapos2, as stated by my second if statement. If after going through all of file 2, it is unable to find a match for aapos, ONLY then do I want to execute the following if statements and check if synonymous in file 1 is equal to 0 or 1 and add 1 to syn2 or nonsyn2, depending on the case. The same applies if for a specific tagname1, the program goes through the entire list of tagname2 in file 2, and is unable to find a match.
However, according to my code, the program only runs once and I get a value of 1 for snps and a value of one for nonsyn2. I'm not sure why this is the case.
for x in range(1,15):
flag = 0
snps = 0
for b in range (1,15):
if tagname1[x]== tagname2[b]:
flag = 1
if int(aapos1[b]) <= int(aapos[x])<= int(aapos2[b]):
snps = snps + 1
if snps == 0:
if int(synonymous[x]) == 0:
nonsyn2 = nonsyn2 + 1
elif int(synonymous[x]) == 1:
syn2 = syn2 + 1
elif flag == 0:
if int(synonymous[x]) == 0:
nonsyn2 = nonsyn2 + 1
elif int(synonymous[x]) == 1:
syn2 = syn2 + 1

Are you sure you mean to break in the lower if statements?
eg:
if int(synonymous[x]) == 0:
nonsyn2 = nonsyn2 + 1
break
These are within the first for loop (for x in range(1,15):) so if one of these conditions is met you will be dropped out of the loop.
If this happens on your first loop, it might be why you only see it run once.
I'm not entirely sure I understand what your trying to do, but the keyword 'continue' might be what you want. It will make the program go to the next iteration of your loop.

Related

How can I check if user input is equal to a value in brainfuck?

I am trying to write a program (which I'm sure has been done before, just trying to challenge myself) that takes two user inputs per loop, one for the letter/number, and one to check if the user is done inputting (y/n), and then print the whole string. I know what I have so far isn't fantastic, but basically I start the loop, move the pointer up two (so there's a findable 0 value at the beginning), ask for the first and second inputs, set the next value to lowercase n, and am currently trying to figure out how to compare the values. I have tried to print values, which only appear to print after two inputs and then the program breaks.
Here is what I have so far:
+[>>[>].,>,>>++++++++++[<+++++++++++>-]<.[->-[>]<<].<[<]<-]
If it makes a difference, I am using a homemade brainfuck interpreter, which may have some imperfections:
def brainfuck(code):
array = [0]
pointer = 0
i = 0
while(i < len(code)):
if(code[i] == '<'):
if(i != 0):
if(pointer != 0):
pointer -= 1
elif(code[i] == '>'):
pointer += 1
if(len(array) <= pointer):
array.append(0)
elif(code[i] == '+'):
array[pointer] += 1
elif(code[i] == '-'):
if(array[pointer] > 0):
array[pointer] -= 1
elif(code[i] == '.'):
print(pointer,chr(array[pointer]))
elif(code[i] == ','):
x = input('Input:')
try:
array[pointer] = int(x)
except ValueError:
array[pointer] = ord(x)
elif(code[i] == '['):
if(array[pointer] == 0):
openBraces = 1
while(openBraces > 0):
i += 1
if(code[i] == '['):
openBraces += 1
elif(code[i] == ']'):
openBraces -= 1
elif(code[i] == ']'):
openBraces = 1
while(openBraces > 0):
i -= 1
if(code[i] == '['):
openBraces -= 1
elif(code[i] == ']'):
openBraces += 1
i -= 1
i += 1
I made something like this a long time ago, should do the trick (if I remember right)
// if x == y: {if_code}; else: {else_code}
,
(x)'y
[->-<]>
0'(y minus x)
[>+>]<
{if} (0)'0; {else} 0'y minus x'(1)
-[
{if_code}
+>>
]<
0'(y minus x)
[
<
{else_code}
>[-]
]<
empty memory
The comments show what memory looks like before each line and they may be structured a bit weirdly in order to avoid using symbols which would be considered as brainfuck by the interpreter. Values in the memory are separated by apostrophes and brackets are used to show which position in the memory the pointer is at.
Make sure to have the value you want to compare the input to in the second position in the memory and to move the pointer back to the first position before implementing this code.
I'm sorry that I didn't read through your interpreter, but I assume that it works.
Hope this helps!
Your interpreter is certainly contributing, at least because decrementing a 0 in it produces a 0 rather than a -1. I haven't checked it for other bugs, but I would suggest using another interpreter. And the main thing I'd suggest is to actually step through your code by hand with pen and paper, command by command, keeping a series of maps of the state of the array. That should show what's happening and where things went off the rails.
(So far, you're outputting a NUL from the third cell, getting input into the third and fourth, putting 110='n' in the 5th, outputting that 'n', moving/negating it in a convoluted way to end up with 0 in the fifth cell and -110 in the sixth, outputting another NUL from the fifth cell, scanning back past your input to the first cell and zeroing it to exit the loop after the first iteration.)
I should note, maybe the simplest way to do what you're trying to do is something like:
>+[,>,>+++++++++++[<----------->-]<]<[<]>[.>]
We read the two bytes and subtract 'y' (121) from the second, then use that to check for loop termination. If the input character was a 'y' the subtraction gives a 0 and we stop the loop; otherwise it gives a positive or negative number and we do the loop again, reading the next character over the residue.
Note, though, that in brainfuck the ',' command reads one character, without prompting. So you'll have to give input like
Hnenlnlnon!y
To get output like
Hello!

using the collatz sequence in dictionaries

I'm pretty new to python and currently, I'm trying to learn dictionaries. I'm trying to write a program that asks the user for a number, and then outputs the number less than or equal to the one the user entered with the longest Collatz sequence.
This is what I currently have right now, but I don't know why it won't work.
def collatz(number):
segLength = {}
for i in range(1, number + 1):
current = 1
count = 0
while current != 1:
if current % 2 == 0:
current = number / 2
elif current % 2 != 0:
current = (3 * number + 1)
count += 1
segLength[i] = count
value = list(segLength.values())
key = list(segLength.keys())
x = max(value)
index = value.index(x)
output = key[index]
return output
result = collatz(number)
print = result
Each iteration of your for loop, you set current = 1, so current != 1 will always be False and you'll skip the while.
It looks like you want to calculate the collatz sequence for each number so I'm guessing you want to instead set current = i.
Then, for each iteration of your for loop, current will have the number you want to reduce to 1 and count the number of steps it takes. To make this work, you'll want to change:
current = number / 2
(and the corresponding 3n+1 line in the elif) to
current = current / 2
because number is always going to be the number you passed into the function at the start, not the number you're trying to run a collatz sequence on this iteration
It looks like it should work otherwise!
EDIT: you should also call print rather than assign to it as Barmar said.

Does "%" divide the length of the word? If so, why does only 'why' come up?

I hope to turn this into an app to remind myself to think every once in a while. I would like to ask 'why'/'why not' every time I put an input in. I wanna make the determinant factor whether or not the length of the notoriginal/alsonotoriginal is even or odd.
print ('Have you thought today?')
original = input('Yes or No:')
if len(original) > 2:
notoriginal = input('When?:')
elif len(original) < 3:
alsonotoriginal = input('Why?:')
while len(notoriginal) % 2 == 0:
input('Why not?:')
while len(notoriginal) % 2 > 0:
input('Why?:')
while len(alsonotoriginal) % 2 == 0:
input('Why not?:')
while len(alsonotoriginal) % 2 > 0:
input('Why?:')
You guys are the best! Thanks!
Edit: Thank you for all your help. I realize this was a pretty simple thing that I messed up. I'd also like to point out that I've since changed the original/notoriginal to better variable names such as second, third, and fourth. I fixed the problem I had, I took your suggestions. What I was confused/forgot about was that you could simply rename variables later in the code and the whole variable would change. What I had was this:
print ('Have you thought today?')
first = input('Yes or No:')
if len(*first*) > 2:
**second** = input('When?:')
elif len(*second*) < 3:
**third** = input('Why?:')
if len(third) % 2 == 0:
fourth = input('Why not?:')
else:
fifth = input('Why?:')
while len(fourth) % 2 == 0:
fifth = input('Why?')
while len(fourth) % 2 > 0:
sixth = input('Why not?')
The problem was that I kept renaming variables, when they didn't have to be renamed and in fact caused an error because they were renamed. I was calling on the code to assess two separate variables when I should've been calling the code to check on a single variable that had two separate outcome values, like so:
print ('Have you thought today?')
first = input('Yes or No:')
if len(first) > 2:
second = input('When?:')
elif len(first) < 3:
second = input('Why?:')
if len(second) % 2 == 0:
third = input('Why not?:')
else:
third = input('Why?:')
while len(third) % 2 == 0:
third = input('Why?')
while len(third) % 2 > 0:
third = input('Why not?')
The % Operand
The % (modulo) operator yields the remainder from the division of the
first argument by the second. The numeric arguments are first
converted to a common type. A zero right argument raises the
ZeroDivisionError exception. The arguments may be floating point
numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.)
The modulo operator always yields a result with the same sign as its
second operand (or zero); the absolute value of the result is strictly
smaller than the absolute value of the second operand
taken from here
To divide len('word') you can use the / operand, but by using the % 2 operation you are able to determine if a number is even or not by analyzing the result, if it returns 0, it is even, if it does not, it is odd, like so:
number = input('Type a number: ')
if number % 2 == 0:
print('Even')
else:
print('Odd')
Why the 'why' input keeps coming up
The reason your code loops and seems to get stuck on the 'why?' question is because you are using while len(notoriginal) % 2 > 0 and while len(alsonotoriginal) % 2 > 0, since the notoriginal and the alsonotoriginal values don't change after the input, you get what is called a 'infinite loop', the same while loop will run forever. To fix this, instead of using while, you could use a if and elif statement, but doing so will require you to fix your code logic, since it's quite flawed at the moment.
Also...
Don't ever call your variables these generic names, it just makes for very confusing debugging later on.

Execute statement between 2 elif blocks

Is there any way to execute statements between the (false) evaluation of 1 elif block and the evaluation of the next in Python 3.x?
I wish to optimise my program by only running the function "word_in_special_list" should the first 2 statements of an if block evaluate as false.
Ideally the program would look something like this:
for word in lis:
#Finds word in list
if word_in_first_list(word):
score += 1
elif word_in_second_list(word):
score -= 1
#Since the first 2 evaluations return false, the following statement is now run
a, b = word_in_special_list(word)
#This returns a Boolean value, and an associated score if it's in the special list
#It is executed only if the word isn't in the other 2 lists,
#and executed before the next elif
elif a:
score += b #Add b to the running score
else:
...other things...
#end if
#end for
Of course, putting a tuple in a elif evaluation returns an error. I also can't restructure my if statement because it is more likely that the word will be in the first or second list, and so this structure saves time. So is there any way to run a code block in between 2 elif evaluations?
You would have to make an else case then nest within that
for word in lis:
if word_in_first_list(word):
score += 1
elif word_in_second_list(word):
score -= 1
else:
a, b = word_in_special_list(word)
if a:
score += b #Add b to the running score
else:
...other things...
You could put in continue statements.
for word in lis:
#Finds word in list
if word_in_first_list(word):
score += 1
continue
if word_in_second_list(word):
score -= 1
continue
a, b = word_in_special_list(word)
if a:
score += b #Add b to the running score
else:
...other things...
I think this has the effect you're trying to achieve. Incidentally, I don't see why you need the function word_in_first_list. What's wrong with if word in first_list?

Division by values in a dictionary (Python)

I am building a prime generator (I know, another one and probably not a very good one at that, but that is for another question.) I am using a dictionary for my collection of primes and ignoring composites by dividing by the previous primes. However it doesn't seem to be iterating properly in the final stage of the function and I get a number of incorrect results. isWhole is a self explanatory call to another function. This is my code where x = the number of primes to be generated:
def prime_generator(x):
count = 2
counter = 2
p = {1: 2}
while len(p) <= x:
if count % 2 == 0:
count += 1
continue
test1 = (math.sqrt(count))
if isWhole(test1) == True:
count += 1
continue
for k, a in p.items():
if count % a == 0:
break
else:
p[ counter ] = count
counter += 1
break
count += 1
return p
Your design intent is not entirely clear, but you may be intending to have the else clause apply to the for loop rather than the if statement. Try un-indenting the entire else clause so that it only runs if the loop terminates without hitting a break.

Categories