edited for clarity. When a loop prints an error message multiple times, it is usually caused by poor control flow. In this case, adding a Breakafter print solved the problem.
Following a simple loop structure with some control flow, is generally a good starting point.
for ...:
if ...:
print ...
break
input_seq = "";
#raw_input() reads every input as a string
input_seq = raw_input("\nPlease input the last 12 nucleotide of the target sequence
before the PAM site.\n\(The PAM site is by default \"NGG\"\):\n12 nt = ")
#print "raw_input =", input_seq
for bases in input_seq:
if not (bases in "ACTGactg"):
print "\nYour input is wrong. Only A.T.C.G.a.t.c.g are allowed for
the input!\n\n";
break
Use break. I am using regular expressions to avoid using a for loop.
input_seq = ""
import re
while True:
#raw_input() reads every input as a string
input_seq = raw_input("\nPlease input the last 12 nucleotide of the target sequence
before the PAM site.\n\(The PAM site is by default \"NGG\"\):\n12 nt = ")
#print "raw_input =", input_seq
if len(input_seq)==12:
match=re.match(r'[ATCGatcg]{12}',input_seq)
if match:
break
else:
print "\nYour input is wrong. Only A.T.C.G.a.t.c.g are allowed for the input!\n\n"
continue
else:
print "\nYour input should be of 12 character"
Add a break after your print statement. That will terminate your loop.
Using a flag to check if there were atleast one wrong input is one way to do it. Like this:
invalid = False
for bases in input_seq:
if not (bases in "ACTGactg"):
invalid = True
if invalid:
print "\nYour input is wrong. Only A.T.C.G.a.t.c.g are allowed for the input!\n\n";
You could alternately use a break statement as soon as you find the first wrong input.
Place a break after the print:
for ...:
if ...:
print ...
break
Related
I've created an empty text file, and saved some stuff to it. This is what I saved:
Saish ddd TestUser ForTestUse
There is a space before these words. Anyways, I wanted to know how to read only 1 WORD in the text file using python. This is the code I used:
#Uncommenting the line below the line does literally nothing.
import time
#import mmap, re
print("Loading Data...")
time.sleep(2)
with open("User_Data.txt") as f:
lines = f.read() ##Assume the sample file has 3 lines
first = lines.split(None, 1)[0]
print(first)
print("Type user number 1 - 4 for using different user.")
ans = input('Is the name above correct?(y/1 - 4) ')
if ans == 'y':
print("Ok! You will be called", first)
elif ans == '1':
print("You are already registered to", first)
elif ans == '2':
print('Switching to accounts...')
time.sleep(0.5)
with open("User_Data.txt") as f:
lines = f.read() ##Assume the sample file has 3 lines
second = lines.split(None, 2)[2]
print(second)
#Fix the passord issue! Very important as this is SECURITY!!!
when I run the code, my output is:
Loading Data...
Saish
Type user number 1 - 4 for using different user.
Is the name above correct?(y/1 - 4) 2
Switching to accounts...
TestUser ForTestUse
as you can see, it diplays both "TestUser" and "ForTestUse" while I only want it to display "TestUser".
When you give a limit to split(), all the items from that limit to the end are combined. So if you do
lines = 'Saish ddd TestUser ForTestUse'
split = lines.split(None, 2)
the result is
['Saish', 'ddd', 'TestUser ForTestUse']
If you just want the third word, don't give a limit to split().
second = lines.split()[2]
You can use it directly without passing any None
lines.split()[2]
I understand your passing (None, 2) because you want to get None if there is no value at index 2,
A simple way to check if the index is available in the list
Python 2
2 in zip(*enumerate(lines.split()))[0]
Python 3
2 in list(zip(*enumerate(lines.split())))[0]
So I want to make it so the print output is in one line, and I did that using end, but my input happens on the same line Shown here. I used the \n on the int, but that indents the program one line when I run it.
while True:
guess = int(input("Number of characters: "))
for i in range(int(guess)):
print(random.choice(letters), end='',)
You do want to use end='' so that all of the print statements in your loop print to the same line. But then, after your loop, you want to output a newline before you accept more input. So you want this:
while True:
guess = int(input("Number of characters: "))
for i in range(int(guess)):
print(random.choice(letters), end='',)
print()
Sample run:
Number of characters: 7
acdeeda
Number of characters: 24
dbffdeebgccdfbfcfdgdbbcf
Number of characters:
I am trying to create a program that reads the text from a text file line by line. For the first 3 lines, the user simply needs to press enter to advance to the next line. For the fourth line, however, they need to press a specific key (the letter "u" in this case). I tried doing this using getch(), but for some reason pressing the "u" key does not generate any response. Here is the code:
from os import path
from msvcrt import getch
trial = 1
while trial < 5:
p = path.join("C:/Users/Work/Desktop/Scripts/Cogex/item", '%d.txt') % trial
c_item = open(p)
print (c_item.readline())
input()
print (c_item.readline())
input()
print (c_item.readline())
input()
print (c_item.readline())
if ord(getch()) == 85:
print (c_item.readline())
input()
trial += 1
I've also read about people using pygame or Tkinter, but I don't know if it is possible to use these without having the program use a graphical interface. Thanks in advance!
The problem with this is that input on most modern ttys is buffered - it is only sent to the application when the enter key is pressed. You can test this in C as well. If you create a GUI application that gets its' keyboard data directly from the OS then yes, you could do this. However, this would likely be more trouble than just asking the user to print the enter key after pressing u.
For example:
result = input()
if result == 'u':
print(c_item.readline())
input()
85 is the ordinal for capital 'U'. For lowercase 'u', you need the ordinal 117.
if ord(getch()) == 117:
You could also simply check whether the character is b'u'.
if getch() == b'u':
Or you could do a case-insensitive check for the ordinal:
if ord(getch()) in (85, 117):
Or for the string:
if getch().lower() == b'u'
You also need to move trial += 1 into the loop:
if getch().lower() == b'u':
print (c_item.readline())
input()
trial += 1
I have done a good many searches but have not been able to find a solution to regex a line and split the values into two variable components. I am using python2.6 and trying to figure out how to regex the integers into value variable and the text into the metric variable. The output information is pulled from a subprocess command running netstat -s.
The below match will only provide the top 6 lines but not the bottom ones where a string is first. I tried using an or conditional within the parenthesis and that did not work, tried (?P<value>[0-9]+|\w+\s[0-9]+) I have been using this site which is really helpful but still no luck, https://regex101.com/r/yV5hA4/3#python
Any help or thoughts of using another method will be appreciated.
Code:
for line in output.split("\n"):
match = re.search(r"(?P<value>[0-9]+)\s(?P<metric>\w+.*)", line, re.I)
if match:
value, metric = match.group('value', 'metric')
print "%s => " % value + metric
What is trying to be regex:
17277 DSACKs received
4 DSACKs for out of order packets received
2 connections reset due to unexpected SYN
10294 connections reset due to unexpected data
48589 connections reset due to early user close
294 connections aborted due to timeout
TCPDSACKIgnoredOld: 15371
TCPDSACKIgnoredNoUndo: 1554
TCPSpuriousRTOs: 2
TCPSackShifted: 6330903
TCPSackMerged: 1883219
TCPSackShiftFallback: 792316
I would just forget about using re here, and just do something like this:
for line in output.split("\n"):
value = None
metric = ""
for word in line.split():
if word.isdigit():
value = int(word)
else:
metric = "{} {}".format(metric, word)
print "{} => {}".format(metric.strip(":"), value)
One slight caveat is that any line that has two or more numbers in it will only report the last one, but that's no worse than how your current approach would deal with that case...
Edit: missed that OP is on Python 2.6, in which case, this should work:
for line in output.split("\n"):
value = None
metric = ""
for word in line.split():
if word.isdigit():
value = int(word)
else:
metric = metric + " " + word
print "%s => %s" % (metric.strip(":"), str(value))
I'm trying to make the following code work:
try:
x = int(input())
except ValueError as var:
#print the input of the user
If I try to print(var) it would print the error line and not the original input of the user.
For example, if the user would insert bla instead of an integer I would like to print bla
P.S I must not change the line x = int(input()), else I would've solved it easily
I would change the x = int(input()) line, but since you ask, here is an ugly hack wich exploits the format of a ValueError message:
invalid literal for int() with base 10: 'foobar'
by splitting it at first : and removing surrounding ':
try:
x = int(input())
except ValueError as e:
original_input = str(e).split(":")[1].strip()[1:-1]
print(original_input)
by the way, if you are still using Python 2.x, you should use raw_input instead of input. In fact old input will automatically attempt a conversion to int if possible:
try:
x = int(raw_input())
except ValueError as e:
original_input = str(e).split(":")[1].strip()[1:-1]
print original_input
What appears when you print var?
Until you provide that information, here is a possible hackish solution:
try:
x = int(input())
except NameError as var:
e = str(var)
print e[6:-16]
This is assuming var is equal to
NameError: name 'user_input' is not defined
where user_input is the user's input.
EDIT: This post assumed the code was running in Python 2.x whereas it seems to be running with Python 3. Leaving this up in case people are wondering for Python 2
This is hack that reads the input from the passed error message. It handles quotes in the input string and backslashes correctly.
#We get input from the user
try:
x = int(input())
except ValueError as var:
#we need to find the text between the quotes in the error message
#but we don't know what kind of quote it will be. We will look for
#the first quote which will be the kind of quotes.
#get the location or existence of each kind of quote
first_dquote = str(var).find('"')
first_squote = str(var).find("'")
used_quote = 0
#if double quotes don't exist then it must be a single quote
if -1 == first_dquote:
used_quote = first_squote
#if single quotes don't exist then it must be a dubble quote
elif -1 == first_squote:
used_quote = first_dquote
#if they both exist then the first one is the outside quote
else: used_quote = min(first_squote,first_dquote)
#the output is what is between the quotes. We leave of the end
#because there is the end quote.
output = str(var)[used_quote+1:-1]
#but the error message is escaped so we need to unescape it
output = bytes(output,"utf_8").decode("unicode_escape")
#print the output
print(output)