I have this error in many solutions.I went through many answers on this topic but could not resolve the problem.I could only figure out that problem could be in taking input from a single input file where the whole input string is taken in one input call and displays EOF error on second raw input call.
def change(a,b,l):
alist = []
blist = []
for m in range(0,26):
alist.append(0)
blist.append(0)
for i in a:
alist[l[i]] += 1
for j in b:
blist[l[j]] += 1
common = 0
for i in range(0,26):
dif = (alist[i] - blist[i])
if (dif != alist[i]):
common += min(alist[i],blist[i])
total = (min(len(a),len(b)) - common) + abs(len(a) - len(b))
return total
test = int(raw_input())
ans = []
l = {}
for i in range(65,91):
l[chr(i)] = i - 65
for i in range(0,test):
a = str(raw_input())
b = str(raw_input())
ans = ans + [change(a,b,l)]
for j in ans:
print j
It would be a great help if someone could describe how to take input at above mentioned multiple times from a single input file.
Especially if you want input from files, and not a terminal, you can use the readline() function of file objects. Example:
import sys
def test(f):
num = int(f.readline())
for i in range(num):
a = int(f.readline())
b = int(f.readline())
print a, b
if __name__ == '__main__':
test(sys.stdin)
You might also want to actually use the end of file as a marker for end of input. In your example you may not for instance require to get the number of records in the first line, but just go on until you hit EOF.
Related
How the loop should iterate. I'm a beginner trying to create a Python program to print a word backwards based on old knowledge from a few years ago. It does a few other things but they are just printed statements are don't pose a problem. Here is my code:
count = 0
while count < 100:
word_var = input("Enter ONE word with NO spaces:")
def split(word_var):
return list(word_var)
word_array = split(word_var)
m = 0
i = len(word_array)-1-m
print("The number of letters in your word is:", i)
while m < len(word_array):
if m < i:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
else:
break
m = m + 1
print(''.join(word_array))
count = count + 1
print("You've typed:",count,"word(s).")
Here is the problem section:
if m < i:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
else:
break
m = m + 1
My main problem is that it seems like the second while loop is not iterating when the word is more than five letters long. For example, if I input the word "should" into the program I get back out dhouls. It seems as if only one interchange of letters is being performed. I figure this is a problem with the if statement in that nested while loop, but I can't seem to find what is wrong with it. I carefully sketched out how I think the if statement works in the photo attached.
Your if condition is wrong. You want to compare the two indices that you will use in the list, but the second one is not i, but i-m. So change it to:
if m < i - m:
This corrects your issue. It should be noted that in Python you can reverse string just like this:
print(word_var[::-1])
There are two issues:
The counting of the letters isn't correct. You should just output the length of word_array.
You're iterating the while loop too many times. You should terminate it when m equals or exceeds len(word_array) // 2. Otherwise, you'll unreverse the letters and get the original word back.
i = len(word_array)-1
print("The number of letters in your word is:", len(word_array))
while m < len(word_array) // 2:
word_array[m], word_array[i - m] = word_array[i - m], word_array[m]
m = m + 1
This outputs:
Enter ONE word with NO spaces:should
The number of letters in your word is: 6
dluohs
You've typed: 1 word(s).
I like your project and appreciate your efforts.
This a another way to reverse a string using a list variable and the insert() method.
word_array = []
word_var = input('Your word : ')
word_array = []
for c in word_var:
word_array.insert(0, c)
word_reversed = ''.join(word_array)
print(word_var, '->', word_reversed)
output :
should -> dluohs
So we have to translate numbers from English to German. I feel I am doing it all wrong because I get no
output when I test my code.
#!/usr/bin/env python3
import sys
english = sys.stdin.read().split()
num = {}
with open("translation.txt") as f:
data = f.read().split("\n")
i = 0
while len(data[i]) < 0:
n = data[i].split()
n1 = n[0]
n2 = n[1]
if n1 not in num:
num[n1] = n2
i = i + 1
i = 0
while i < len(english):
n = english[i]
if n in num:
print(num[n])
i = i + 1
Please help. Am I even getting the code to open the text file? the text file contains numbers translated from English to German
Example of translation.txt
one: eins
two: zwei
three: drei
four: vier
five: funf
six: sechs
seven: sieben
eight: acht
nine: neun
ten: zehn
Well, your code had some major logical errors. First of all, a comparison was wrong for the loops. You also split the line but you left : in the keys. Also checking if the word already exists is not necessary, but I left it as you wrote. I also added two side translation just in case you will need it.
Here is my implementation of the problem:
#!/usr/bin/env python3
import sys
english = sys.stdin.read().split()
num = {}
with open("translation.txt") as f:
data = f.read().split("\n")
i = 0
while i < len(data):
n = data[i].split()
print(n)
n1 = n[0].replace(':', '')
n2 = n[1]
if n1 not in num and n2 not in num:
num[n1] = n2
num[n2] = n1
i = i + 1
print(num['one'])
print(num['eins'])
You read inputs from standard input via sys.stdin.read(). This requires reading ALL characters until an EOF is met, which would happen only if:
An EOF is entered via the keyboard (Ctrl-D for Unix-based systems and Ctrl-Z for Windows);
The input is redirected from another stream that ends with an EOF, such as a file stream.
If the input is entered line by line via the keyboard, the output won't be seen until an EOF is seen. If it is desired that the output is shown immediately after one line of input, input() should be used instead of sys.stdin.read().
Other issues have been explained in #Raguel's answer.
Here we have a major issue with application logic, as were mentioned in previous answers:
First of all, we need to load dictionary - our resource to operate.
Second, we can start the translation, for example word-by-word from continues user input
The compact solution (require python 3.8):
#!/usr/bin/env python3
with open("translation.txt", "r") as f:
dictionary = { k: v.strip() for k, v in [line.split(":") for line in f.readlines()]}
while word:=input("Word to translate: "):
try:
print(dictionary[word])
except KeyError:
print(f"No translation found for the word: {word}")
I am having problems with CS50 pset6 DNA. It is getting all the right values and gives correct answers when I use the small.csv file but not when I use the large one. I have been going through it with debug50 for over a week and can't figure out the problem. I assume the problem is somewhere in the loop through the samples to find the STRS but I just don't see what it is doing wrong when walking through it.
If you are unfamiliar with CS50 DNA problemset, the code is supposed to look through a dna sequence (argv[1]) and compare it with a CSV file containing people DNA STRs to figure out which person (if any) it belongs to.
Note; My code fails within the case; (Python dna.py databases/large.csv sequences/5.txt) if this helps.
from sys import argv
from csv import reader
#ensures correct number of arguments
if (len(argv) != 3):
print("usage: python dna.py data sample")
#dict for storage
peps = {}
#storage for strands we look for.
types = []
#opens csv table
with open(argv[1],'r') as file:
data = reader(file)
line = 0
number = 0
for l in data:
if line == 0:
for col in l:
if col[2].islower() and col != 'name':
break
if col == 'name':
continue
else:
types.append(col)
line += 1
else:
row_mark = 0
for col in l:
if row_mark == 0:
peps[col] = []
row_mark += 1
else:
peps[l[0]].append(col)
#convert sample to string
samples = ""
with open(argv[2], 'r') as sample:
for c in sample:
samples = samples + c
#DNA STR GROUPS
dna = { "AGATC" : 0,
"AATG" : 0,
"TATC" : 0,
"TTTTTTCT" : 0,
"TCTAG" : 0,
"GATA" : 0,
"GAAA" : 0,
"TCTG" : 0 }
#go through all the strs in dna
for keys in dna:
#the longest run of sequnace
longest = 0
#the current run of sequances
run = 0
size = len(keys)
#look through sample for longest
i = 0
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
if run > longest:
longest = run
run = 0
i += 1
dna[keys] = longest
#see who it is
positive = True
person = ''
for key in peps:
positive = True
for entry in types:
x = types.index(entry)
test = dna.get(entry)
can = int(peps.get(key)[x])
if (test != can):
positive = False
if positive == True:
person = key
break
if person != '':
print(person)
else:
print("No match")
Problem is in this while loop. Look at this code carefully.
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
if run > longest:
longest = run
run = 0
i += 1
You have a missing logic here. You are supposed to check the longest consecutive DNA sequence. So when you have a repetition of dna sequence back to back, you need to find how many times it is repeated. When it is no longer repeated, only then, you need to check if this is the longest sequence.
Solution
You need to add else statement after if hold==keys: statement. This would be the right fix;
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples
if ((i + size) < len(samples)):
i = i + size
continue
else: #only if there is no longer sequence match, check this.
if run > longest:
longest = run
run = 0
else: #if the number of sequence match is still smaller then longest, then make run zero.
run = 0
i += 1
earik87 is absolutely right! Just I like to add, the code is missing an = to work for all the cases especially when you have redundant sequences.
while i < len(samples):
hold = samples[i:(i + size)]
if hold == keys:
run += 1
#ensure the code does not go outside len of samples **( I added =)**
if ((i + size) <= len(samples)):
i = i + size
continue
else: #only if there is no longer sequence match, check this.
if run > longest:
longest = run
run = 0
else: #if the number of sequence match is still smaller then longest, then make run zero.
run = 0
i += 1
I’m using Python IDE 3. My goal is this: If I have a string of text, ‘ABCDEFGHIJKL’, I want to sort it into groups, like three groups (‘ADGJ’,’BEHK’,’CFIL’). I require input for this, but the prompts aren’t showing up and I can’t type in input. Here’s my code:
#data
code_text = input('Text: ').lower()
code_skip = int(input('Shift length: '))
code_list = []
#function
def countSkip(text, shift, listt):
i = 0
group = 1
if group <= shift:
for e in text:
#make sure the set starts at the right place
if e.index()+1 < group:
pass
elif shift != 0:
if i = shift:
listt.append(e)
i = 0
i += 1
else:
listt.append(e)
group += 1
Calling the function
countSkip(code_text, code_shift, code_list)
There's a few things stopping your code from working that people have pointed out in the comments. Instead of trying to dissect your code and get that to work, I wrote a much more concise function that will get you the results you're after
def text_splitter(input_text, set_length):
num_sets = int(len(input_text)/set_length)
split_text = ["".join([input_text[(n * num_sets) + m] for n in range(set_length)]) for m in range(num_sets)]
return split_text
text_to_split = input('Text: ').lower()
len_set = int(input('Set Length: '))
text_list = text_splitter(text_to_split, len_set)
Sorry I was struggling to name the variables in an effective manner but the function above uses a list expression to get you the results you need. Keep in mind that if you use say a 7 letter string and ask for sets of length 2, the last letter won't be appended. However this shouldn't be too hard to check and correct. For example you could add this code to the function or around the initial input for the set length:
while len(input_text) % set_length != 0:
set_length = int(input("The text is length " + str(len(input_text)) + " please enter a different set length: "))
This is what I have to do https://www.codeeval.com/open_challenges/140/
I've been on this challenge for three days, please help. It it is 85-90 partially solved. But not 100% solved... why?
This is my code:
import sys
test_cases = open(sys.argv[1], 'r')
for test in test_cases:
saver=[]
text=""
textList=[]
positionList=[]
num=0
exists=int()
counter=0
for l in test.strip().split(";"):
saver.append(l)
for i in saver[0].split(" "):
textList.append(i)
for j in saver[1].split(" "):
positionList.append(j)
for i in range(0,len(positionList)):
positionList[i]=int(positionList[i])
accomodator=[None]*len(textList)
for n in range(1,len(textList)):
if n not in positionList:
accomodator[n]=textList[len(textList)-1]
exists=n
for item in positionList:
accomodator[item-1]=textList[counter]
counter+=1
if counter>item:
accomodator[exists-1]=textList[counter]
for word in accomodator:
text+=str(word) + " "
print text
test_cases.close()
This code works for me:
import sys
def main(name_file):
_file = open(name_file, 'r')
text = ""
while True:
try:
line = _file.next()
disordered_line, numbers_string = line.split(';')
numbers_list = map(int, numbers_string.strip().split(' '))
missing_number = sum(xrange(sorted(numbers_list)[0],sorted(numbers_list)[-1]+1)) - sum(numbers_list)
if missing_number == 0:
missing_number = len(disordered_line)
numbers_list.append(missing_number)
disordered_list = disordered_line.split(' ')
string_position = zip(disordered_list, numbers_list)
ordered = sorted(string_position, key = lambda x: x[1])
text += " ".join([x[0] for x in ordered])
text += "\n"
except StopIteration:
break
_file.close()
print text.strip()
if __name__ == '__main__':
main(sys.argv[1])
I'll try to explain my code step by step so maybe you can see the difference between your code and mine one:
while True
A loop that breaks when there are no more lines.
try:
I put the code inside a try and catch the StopIteracion exception, because this is raised when there are no more items in a generator.
line = _file.next()
Use a generator, so that way you do not put all the lines in memory from once.
disordered_line, numbers_string = line.split(';')
Get the unordered phrase and the numbers of every string's position.
numbers_list = map(int, numbers_string.strip().split(' '))
Convert every number from string to int
missing_number = sum(xrange(sorted(numbers_list)[0],sorted(numbers_list)[-1]+1)) - sum(numbers_list)
Get the missing number from the serial of numbers, so that missing number is the position of the last string in the phrase.
if missing_number == 0:
missing_number = len(unorder_line)
Check if the missing number is equal to 0 if so then the really missing number is equal to the number of the strings that make the phrase.
numbers_list.append(missing_number)
Append the missing number to the list of numbers.
disordered_list = disordered_line.split(' ')
Conver the disordered phrase into a list.
string_position = zip(disordered_list, numbers_list)
Combine every string with its respective position.
ordered = sorted(string_position, key = lambda x: x[1])
Order the combined list by the position of the string.
text += " ".join([x[0] for x in ordered])
Concatenate the ordered phrase, and the reamining code it's easy to understand.
UPDATE
By looking at your code here is my opinion tha might solve your problem.
split already returns a list so you do not have to loop over the splitted content to add that content to another list.
So these six lines:
for l in test.strip().split(";"):
saver.append(l)
for i in saver[0].split(" "):
textList.append(i)
for j in saver[1].split(" "):
positionList.append(j)
can be converted into three:
splitted_test = test.strip().split(';')
textList = splitted_test[0].split(" ")
positionList = map(int, splitted_test[1].split(" "))
In this line positionList = map(int, splitted_test[0].split(" ")) You already convert numbers into int, so you save these two lines:
for i in range(0,len(positionList)):
positionList[i]=int(positionList[i])
The next lines:
accomodator=[None]*len(textList)
for n in range(1,len(textList)):
if n not in positionList:
accomodator[n]=textList[len(textList)-1]
exists=n
can be converted into the next four:
missing_number = sum(xrange(sorted(positionList)[0],sorted(positionList)[-1]+1)) - sum(positionList)
if missing_number == 0:
missing_number = len(textList)
positionList.append(missing_number)
Basically what these lines do is calculate the missing number in the serie of numbers so the len of the serie is the same as textList.
The next lines:
for item in positionList:
accomodator[item-1]=textList[counter]
counter+=1
if counter>item:
accomodator[exists-1]=textList[counter]
for word in accomodator:
text+=str(word) + " "
Can be replaced by these ones:
string_position = zip(textList, positionList)
ordered = sorted(string_position, key = lambda x: x[1])
text += " ".join([x[0] for x in ordered])
text += "\n"
From this way you can save, lines and memory, also use xrange instead of range.
Maybe the factors that make your code pass partially could be:
Number of lines of the script
Number of time your script takes.
Number of memory your script uses.
What you could do is:
Use Generators. #You save memory
Reduce for's, this way you save lines of code and time.
If you think something could be made it easier, do it.
Do not redo the wheel, if something has been already made it, use it.