join user input at index of inputs - python

I can't seem to figure out why I can't get this loop to loop - it always breaks instead. I believe if it was looping, the script (hopefully) would be working as instructed.
I've attached the instructions to the script and inline to explain my thinking.
Tahnks!
script accepts user inputs, and every time script receives a string, it should add the string to a growing string. Newly added strings should be added to the growing string at the index equal to the newly added string's length. If the newly added string's length is equal to or larger than the growing string, this script should add the new string to the end of the growing string. When this script receives a blank input, this application should stop receiving input and print the growing string to the console.
if __name__ == "__main__":
user_word = input()
second_word = input()
results = user_word + second_word[:]
i = results
while results == "": # When script receives a blank input
print(results) # stop receiving input and print the growing string
break
if user_word >= results: # if newly added string length equal to or larger
results = user_word + second_word[:]
user_word.join(results) # the new string added to end of the growing string.
print(results)
if user_word < results: # new string is shorter than the existing string THEN
results = user_word + second_word[:] # add the new string at the index equal to the new string length.
user_word.join(results) # Newly added strings should be added to the growing string
print(results)

s = ''
while True:
user_word = input('Enter string')
if len(user_word) >= len(s):
s = s + user_word
elif user_word == '':
print(s)
break
else:
s = s[:len(user_word)] + user_word + s[len(user_word):]

Related

CS50 Pset6 DNA: Trying to accessing data from a file, getting a "I/O operation on closed file."

Just need the function: "def scan_for_matches(db_csv, list_sub_seq):" to be able to access the "db_csv" parameter.
When attempting to run code, I get the I/O operation on closed file error message in the terminal.
I don't understand what I'm getting wrong, I know the "with open()" method closes files after operations, but I have the file read into memory, stored in the "db_csv" variable.
What am I doing wrong? Do I need to manually open and close this file to make this code run?
import csv
from sys import argv
#Returns length of longest consecutive run of subsequence in sequence.
#This function is written by Harvard cs50 people and provided to students, I have not modified it.
def longest_match(sequence, subsequence):
# Initialize variables
longest_run = 0
subsequence_length = len(subsequence)
sequence_length = len(sequence)
# Check each character in sequence for most consecutive runs of subsequence
for i in range(sequence_length):
# Initialize count of consecutive runs
count = 0
# Check for a subsequence match in a "substring" (a subset of characters) within sequence
# If a match, move substring to next potential match in sequence
# Continue moving substring and checking for matches until out of consecutive matches
while True:
# Adjust substring start and end
start = i + count * subsequence_length
end = start + subsequence_length
# If there is a match in the substring
if sequence[start:end] == subsequence:
count += 1
# If there is no match in the substring
else:
break
# Update most consecutive matches found
longest_run = max(longest_run, count)
# After checking for runs at each character in sequence, return longest run found.
return longest_run
#Check database for matching profiles
def scan_for_matches(db_csv, list_sub_seq):
for row in db_csv:
person = row[0]
profile = [ int(x) for x in row[1:] ]
if profile == list_sub_seq:
print(person)
return
print("No match.")
#can not access db_csv. says file is closed.
def main():
#Check for command-line usage
if len(argv) != 3:
print("Usage: python dna.py data.csv sequence.txt")
#Read database file into a variable
#this is where I'm having problems, the file is open for these operations but
#but not for use later for the function scan_for_matches():
#where db_csv is created.
with open(argv[1]) as database:
db_csv = csv.reader(database)
STR_count = next(db_csv)[1:]
print("STR:", STR_count)
for row in db_csv:
print(row)
#Read DNA sequence file into a variable
with open(argv[2]) as sequences:
seq = sequences.read()
#print(seq)
#Find longest match of each STR in DNA sequence
list_sub_seq = [longest_match(seq, x) for x in STR_count]
print(list_sub_seq)
scan_for_matches(db_csv, list_sub_seq)
main()

Using function returns with None

Write a function file_in_english(filename, character_limit) that takes a filename (as a str) and a character_limit (as an int). The filename is the name of the file to convert from Cat Latin to English and the character limit is the maximum number of characters that can be converted. The limit is on the total number of characters in the output (including newline characters).
The function should return a string that contains all the converted lines in the same order as the file - remember the newline character at the end of each line (that is make sure you include a newline character at the end of each converted line so that it is included in the line's length).
If the limit is exceeded (ie, a converted sentence would take the output over the limit) then the sentence that takes the character count over the limit shouldn't be added to the output. A line with "<>" should be added at the end of the output instead. The processing of lines should then stop.
The lines in the file will each be a sentence in Weird Latin and your program should print out the English version of each sentence
The function should keep adding sentences until it runs out of input from the file or the total number of characters printed (including spaces) exceeds the limit.
The answer must include your definition of english_sentence and its helper(s) functions - that I should have called english_word or similar.
You MUST use while in your file_in_english function.
You can only use one return statement per function.
The test file used in the examples (test1.txt) has the following data:
impleseeoow estteeoow aseceeoow
impleseeoow estteeoow aseceeoow ineleeoow 2meeoow
impleseeoow estteeoow aseceeoow ineleeoow 3meeoow
impleseeoow estteeoow aseceeoow ineleeoow 4meeoow
I program works fine except that sometimes it returns None.
def english_sentence(sentence):
"""Reverse Translation"""
consonants = 'bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ'
eng_sentence = []
for coded_word in sentence.split():
if coded_word.endswith("eeoow") and (coded_word[-6] in consonants):
english_word = coded_word[-6] + coded_word[:-6]
if (coded_word[-6] == 'm') and (coded_word[0] not in consonants):
english_word = '(' + english_word + ' or ' + coded_word[:-6] + ')'
eng_sentence.append(english_word)
return " ".join(eng_sentence)
def file_in_english(filename, character_limit):
"""English File"""
newone = open(filename)
nowline = newone.readline()
characters = 0
while characters < character_limit and nowline != "":
process = nowline[0:-1]
print(english_sentence(process))
characters += len(nowline)
nowline = newone.readline()
if characters > character_limit:
return("<<Output limit exceeded>>")
ans = file_in_english('test1.txt', 20)
print(ans)
Output is:
simple test case
simple test case line (m2 or 2)
simple test case line (m3 or 3)
simple test case line (m4 or 4)
None
But I must use only one return statement in each function. How can I do that for the second function and avoid the "None" in output?
You're doing the same thing as:
def f():
print('hello')
print(f())
So basically narrows down to:
print(print('hello world'))
Also btw:
>>> type(print('hello'))
hello
<class 'NoneType'>
>>>
To solve your code do:
def file_in_english(filename, character_limit):
s=""
"""English File"""
newone = open(filename)
nowline = newone.readline()
characters = 0
while characters < character_limit and nowline != "":
process = nowline[0:-1]
s+=english_sentence(process)+'\n'
characters += len(nowline)
nowline = newone.readline()
if characters > character_limit:
s+="<<Output limit exceeded>>"
return s
ans = file_in_english('test1.txt', 20)
print(ans)
You have to make sure, that any function that should return something, does this for ALL ways that your function can end.
Your function file_in_english only returns something for the case if characters > character_limit:
If charachter == or charachter < character_limit this is not the case, the function returns nothing explicitly.
Any function that does not return something from it on end, implicitly returns None when it returns to its caller.
def something(boolean):
"""Function that only returns something meaninfull if boolean is True."""
if boolean:
return "Wow"
print(something(True)) # returns Wow
print(something(False)) # implicitly returns/prints None
You can find this fact f.e. in the python tutorial:
Coming from other languages, you might object that fib is not a
function but a procedure since it doesn’t return a value. In fact,
even functions without a return statement do return a value, albeit a
rather boring one. This value is called None (it’s a built-in name).
Writing the value None is normally suppressed by the interpreter if it
would be the only value written. You can see it if you really want to
using print():
Source:https://docs.python.org/3.7/tutorial/controlflow.html#defining-functions - just short after the 2nd green example box

Splice a string, multiple times, using a keyword

I am trying to break a string apart by removing segments that occur between two words.
Example:
AGCGUGUGAGAGCUCCGA
I will remove the parts that occur between: GUGU and AGAG
So, the new string will be:
AGCCUCCGA
I wrote a code that utilises while loop to keep 'splicing' a string over and over till it can't find the GUGU and AGAG in the string. The process works, most of the time.
I encountered one case where the 'input' is extremely long and then my code is stuck in an infinite loop and I don't understand why that is the case.
I was hoping that someone could review it and help me improve on what I am doing.
def splice(strand):
while True:
initial = strand.find('GUGU')
final = strand.find('AGAG')
if initial == -1:
break
if final == -1:
break
strand = strand[:initial] + strand[final+4:]
return strand
if __name__ == "__main__":
strand = input("Input strand: ")
print()
spliced = splice(strand)
print("Output is {}".format(spliced))
The case where it is failing is:
GUGUAGAGGUCACAGUGUAAAAGCUCUAGAGCAGACAGAUGUAGAGGUGUUGUGUAACCCGUAGAGCAAAGGCAACAGUGUGUAAAGAGGUGUAAAGAG
Expected result:
GUCACACAGACAGAUGUAGAGCAAAGGCAACA
I haven't encountered any other cases where the code will not work.
Your code doesn't work if AGAG is right before GUGU. After the first iteration on that input, the value of strand is
GUCACACAGACAGAUGUAGAGGUGUUGUGUAACCCGUAGAGCAAAGGCAACAGUGUGUAAAGAGGUGUAAAGAG
Then initial is 21 and final is 17, so you do:
strand = strand[:21] + strand[21:]
which just sets strand back to the same value, so you get stuck in a loop.
The string.find() method has an optional start argument, so you can tell it to start looking for AGAG after initial:
final = strand.find("AGAG", initial+4)
You can also do the whole thing with a regexp substitution:
import re
strand = re.sub(r'GUGU(.*?)AGAG', '', strand)
import re
pattern = '(.*?)GUGU.*?AGAG'
s1 = 'AGCGUGUGAGAGCUCCGA'
s2 = 'GUGUAGAGGUCACAGUGUAAAAGCUCUAGAGCAGACAGAUGUAGAGGUGUUGUGUAACCCGUAGAGCAAAGGCAACAGUGUGUAAAGAGGUGUAAAGAG'
print ''.join(re.findall(pattern,s1)) + s1[s1.rfind('AGAG')+4:]
print ''.join(re.findall(pattern,s2)) + s2[s2.rfind('AGAG')+4:]
AGCCUCCGA
GUCACACAGACAGAUGUAGAGCAAAGGCAACA

Iteration issue in python

[Code below question]
The idea is to expand on python's built-in split() function. This function takes two strings, one that needs to be split, and the second is what characters to omit and split at in the first string. This code has worked, but for some reason with this input, it will not iterate anything past the last comma. In other words, no matter the input in this format, it won't append anything past the final comma. I can't figure out why. I have gone line through line of this code and I can't find out where I am losing it.
Why is my code not iterating through any characters past the last comma?
def split_string(source,splitlist):
## Variables ##
output = []
start, start_pos , tracker = 0 , 0 , 0
## Iterations ##
for char in source:
start = source.find(char,start)
if char in splitlist:
tracker += 1
if tracker <= 1:
end_pos = source.find(char, start)
output.append(source[start_pos:end_pos])
start_pos = end_pos + 1
else:
start_pos+=1
else:
tracker = 0
return output
out = split_string("First Name,Last Name,Street Address,City,State,Zip Code",",")
print out
Because your code does not have any code to append from the last comma till the end of string.
end_pos = source.find(char, start)
output.append(source[start_pos:end_pos])
Your need to finally append a range between last comma and string length.
Add the following after the loop ends.
output.append(source[end_pos+1:];
Modified code:
http://ideone.com/9Khu4g

Python: How to make a script to continue after a valid string variable is returned

I got a question about a flow of definition in python:
def testCommandA () :
waitForResult = testCommandB ()
if result != '' :
print 'yay'
Is there any way to make waitForResult to wait for testCommandB to return something (not just an empty string)? Sometimes testCommandB will produce nothing (empty string) and I do not want to pass empty string but as soon as I got a string in waitForResult then testCommandA will continue to run. Is it possible?
Thanks in advance
# Start with an empty string so we run this next section at least once
result = ''
# Repeat this section until we get a non-empty string
while result == '':
result = testCommandB()
print("result is: " + result)
Note that if testCommandB() doesn't block, this will cause 100% CPU utilization until it finishes. Another option is sleep between checks. This version checks every tenth of a second:
import time
result = ''
while result == '':
time.sleep(0.1)
result = testCommandB()
print("result is: " + result)
Just return from testCommandB only where it's not an empty string. ie, have testCommandB block until it has a meaningful value.

Categories