the program get the ls directory list print the index of the items, then ask select one item, and print the item but i get this error:
./directory.py
from: can't read /var/mail/subprocess
./directory.py: línea 3: error sintáctico cerca del elemento inesperado `('
./directory.py: línea 3: `def listdir (path):'
this is my code
from subprocess import Popen, PIPE
def listdir (path):
p = Popen(['ls', path,'-t'] , shell=False, stdout=PIPE, close_fds=True)
return [path.rstrip('\n') for path in p.stdout.readlines()]
def find(f, seq):
for item in seq:
if f == item:
return item
def listshow(l,i):
for item in l:
print i, item
i = i + 1
dirlist = listdir("/home/juan/")
val = 0
listshow(dirlist, val)
while True:
try:
line = raw_input()
except EOFError:
if not line: break
print dirlist[line]
You are using strings as list indexes, so it will not work. Change this portion of code
while True:
try:
line = raw_input()
except EOFError:
if not line: break
with this
value = None
while True:
try:
line = raw_input()
if not line: break
else:
value = int(line)
break
except ValueError:
print "You have not provided a valid integer"
Also note that you are using the index that user gave you without checking it really exists on the array. So you may also do something like this:
try:
print dirlist[line]
except IndexError:
print "Nope, that element does not exists..."
or check this while after you get the number (check if the number given is between 0 and len(dirlist)-1).
Related
So, I'm doing this assignment and I can't seem to figure out how to continue on to the next step.
assignment output example
The file numbers.txt contains the following numbers all on separate lines (25, 15, 5, six, 35, one, 40).
My problem is that I can only print out one ValueError message (six), but I need to be able to print out both messages (invalid literal for int() with base 10: 'six\n', invalid literal for int() with base 10: 'one\n').
Since I can't get the codes to move on to the next iteration, my average only adds 25, 15, and 5.
I've only been learning Python for a month so I don't know if there's a simple way to solve all these problems.
Below is the code I am working on.
def main():
while True:
try:
filename = input("Enter a file name: ")
infile = open(filename, "r")
except IOError:
print("[Error No. 2] No such file or directory:", filename)
continue # continue to next iteration
else:
break
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
try:
infile = open(filename, "r") #somehow without this, the first line won't print
for line in infile:
num = int(line)
print(num)
total += num
count += 1
print("The average is: ", total/count)
except ValueError as err:
print(err)
finally:
print(total/count)
main()
You can repositioning your try statement in the second loop like so:
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
infile = open(filename, "r")
for line in infile:
try:
num = int(line)
print(num)
total += num
count += 1
except ValueError as err:
print(err)
print("The average is: ", total/count)
This way, you won't exit the loop once you encounter an error message, and will simply print it and move on to the next line.
Try the below
# open the file using 'with' - it will make sure that the file will be closed
with open('input.txt') as f:
values = []
# read the lines into a list
lines = [l.strip() for l in f.readlines()]
for line in lines:
# try to convert to int
try:
x = int(line)
values.append(x)
except ValueError as e:
print(e)
# calculate the average
print(f'Avg: {sum(values)/len(values)}')
input.txt
25
15
5
six
35
one
40
output
invalid literal for int() with base 10: 'six'
invalid literal for int() with base 10: 'one'
Avg: 24.0
You need to indent your while True as currently the main function is causing an error.
You should also do an if line == ‘six’:
line = 6
You can set the try-except block inside the for loop which should produce the correct results.
data = infile.readline().strip()
numbers = data.split()
total = 0
count = 0
infile = open(filename, "r")
for line in infile:
try:
num = int(line)
total += num
count += 1
except ValueError as err:
print(err)
print("The average is: ", total/count)
EOF error is occurring in this step method, val = input().split(' ') value error occurs when I remove the try block
from collections import deque
n = int(input())
d = deque()
for _ in range(n):
try:
method, val = input().split(' ')
if method == 'append':
d.append(val)
if method == 'appendleft':
d.appendleft(val)
except ValueError:
a = input()
if str(a) == 'pop':
d.pop()
else:
d.popleft()
print(d)
Input given is :
6
append 1
append 2
append 3
appendleft 4
pop
popleft
You have problem because you use input() inside except so in one loop it reads two lines - first in try and next in except - so finally you have less lines.
Error ValueError is raised by method, val = ... which is executed after input() - so this line is already removed from buffer and you have less lines in buffer. And when you runs next input() in except then it doesn't read the same line but next line - so you get too many lines in one loop.
You should first read line and assign to single variable and later you should try to split it into two variables.
line = input()
try:
method, val = line.split(' ')
# ... code ...
except ValueError:
method = line
# ... code ...
Instead of try/except you could first split line and assing to single variable
#args = input().strip().lower().split(' ')
args = input().split(' ')
and later check len(args)
args = input().strip().lower().split(' ')
if len(args) == 2:
method = args[0]
val = args[1]
# ... code ...
elif len(args) == 1:
method = args[0]
# ... code ...
else:
print('Wrong number of arguments')
I need to read multiple lines from user input, parse them as commands and call functions. I keep getting EOFError even after I have threw an exception. Same thing happens if I put the if..else statements inside 'try'. The program stops at main and wouldn't call the functions.
EDITED
infile = open('file.csv')
weather = list()
for line in infile:
parse_one_line() #parse each row into tuples
#and add them into a list
while True:
try:
input_stream = input()
command = input_stream.split()
except ValueError:
pass
if command == []:
pass
elif command[:4] == ['filter', 'TEMP', 'at', 'least']:
filterRecord() #user input "filter TEMP at least <integer>"
elif ...
def filterRecord(): #filter rows that meet
#the criteria into a new list
global filtered
filtered = list()
try:
for x in range(len(weather)):
if int(weather[x][2]) >= int(command[-1]):
print(weather[x])
filtered.append(tuple(weather[x]))
except ValueError:
pass
The problem is probably with this line
elif: command == '..'
The colon is in the wrong place, change it to
elif command == '..':
I want to be able to have a program whereby the user can input a paragraph/sentence/word/character whatever and have that stored in a list e.g. in list[0]. Then I want them to be able to write another bit of text and have that stored in e.g. list[1]. Then at any time I want the user to be able to read that from the list by choosing which segment they want to read from e.g. reading "hello" from list[0] whilst in list[1] "hi" is stored. Then when the user exits the program I want the list to be written to an external file. Then, at next start up, the program should read the file contents and store it again in the list so that the user can add more bits of text or read the current bits. When the list is saved to a file it should append new or changed parts but overwrite parts that are the same so as not to have duplicates. I have attempted this without much success. I am to be honest not sure if it is possible. I have browsed similar forums and have found that hasn't helped much so here it is.
My code so far:
import os
import time
import csv
global write_list
global f1_contents
write_list = []
def write():
os.system("cls")
user_story = input("Enter your text: \n")
write_list.append(user_story)
def read():
os.system("cls")
user_select_needs = True
while user_select_needs == True:
user_select = input("Enter the list section to read from or type exit: \n")
if user_select == "exit":
user_select_needs = False
try:
int(user_select)
select = user_select
select = int(select)
try:
print(write_list[select])
user_select_needs = False
enter = input("Press enter:")
except:
print("There is not stored data on that section!")
except ValueError:
print("That is not a valid section!")
def exit():
os.system("cls")
max_num_needs = True
while max_num_needs == True:
set_max_num = input("Set the storage: \n")
try:
int(set_max_num)
max_num = set_max_num
max_num = int(max_num)
max_num_needs = False
except:
print("It must be an integer!")
for i in range(0, max_num):
f = open("Saves.txt", "a")
f.write(write_list[i])
f.close()
os._exit(1)
def main():
store_num_needs = True
while store_num_needs == True:
set_store_num = input("State the current storage amount: \n")
try:
int(set_store_num)
store_num = set_store_num
store_num = int(store_num)
store_num_needs = False
except:
print("It must be an integer!")
try:
f1 = open("Saves.txt", "r")
for i in range(0, store_num+1):
i, = f1.split("#")
f1.close()
except:
print("--------Loading-------")
time.sleep(1)
while True:
os.system("cls")
user_choice = ""
print("Main Menu" + "\n" + "---------")
print("1) Write")
print("2) Read")
print("3) Exit")
while user_choice not in ["1", "2", "3"]:
user_choice = input("Pick 1, 2 or 3 \n")
if user_choice == "1":
write()
elif user_choice == "2":
read()
else:
exit()
if __name__ == "__main__":
main()
It might be too complicated to understand in which case just ask me in comments- otherwise general tips would be nice aswell.
Thanks in advance
A quick point of correction:
global is only required if you're defining a global variable inside a non-global context. In other words, anything defined at the default indentation level, will be accessible by everything else defined below it. For example:
def set_global():
x = 1
def use_global():
x += 1
set_global()
try:
use_global()
except Exception as e:
# `use_global` doesn't know
# about what `set_global` did
print("ERROR: " + str(e))
# to resolve this we can set `x` to a
# default value in a global context:
x = 1
# or, if it were required, we
# could create a global variable
def make_global():
global x
make_global()
# either will work fine
set_global()
use_global()
print(x) # prints 2
Now to the actual question:
I haven't read through the block of code you wrote (probably best to trim it down to just the relevant bits in the future), but this should solve the problem as I understand it, and you described it.
import os
import sys
user_text = []
# login the user somehow
user_file = 'saves.txt'
def writelines(f, lines):
"""Write lines to file with new line characters"""
f.writelines('\n'.join(lines))
def readlines(f):
"""Get lines from file split on new line characters"""
text = f.read()
return text.split('\n') if text else []
class _Choice(object):
"""Class that is equivalent to a set of choices
Example:
>>> class YesObj(Choice):
>>> options = ('y', 'yes')
>>> Yes = YesObj()
>>> assert Yes == 'yes'
>>> assert Yes == 'y'
>>> # assertions evaluate to True
Override the `options` attribute to make use
"""
allowed = ()
def __eq__(self, other):
try:
s = str(other)
except:
raise TypeError("Cannot compare with non-string")
else:
return s.lower() in self.allowed
def _choice_repr(choices):
allowed = []
for c in choices:
if isinstance(c, _Choice):
allowed.extend(c.allowed)
else:
allowed.append(c)
if len(allowed) > 2:
s = ', '.join([repr(c) for c in allowed[:-1]])
s += ', or %s' % repr(allowed[-1])
elif len(allowed) == 1:
s = '%s or %s' % allowed
else:
s = '%s' % allowed[0]
return s
def _choice_sentinel(name, allowed):
"""Creates a sentinel for comparing options"""
return type(name, (_Choice,), {'allowed': list(allowed)})()
Quit = _choice_sentinel('Quit', ('q', 'quit'))
Yes = _choice_sentinel('Yes', ('y', 'yes'))
No = _choice_sentinel('No', ('n', 'no'))
def readline_generator(f):
"""Generate a file's lines one at a time"""
t = f.readline()
# while the line isn't empty
while bool(t):
yield t
t = f.readline()
def read_from_cache():
"""Overwrite `user_text` with file content"""
if not os.path.isfile(user_file):
open(user_file, 'w').close()
globals()['user_text'] = []
else:
with open(user_file, 'r') as f:
lines = readlines(f)
# replace vs extend user text
for i, t in enumerate(lines):
if i == len(user_text):
user_text.extend(lines[i:])
else:
user_text[i] = t
def write_to_cache():
"""Overwrite cache after the first line disagrees with current text
If modifications have been made near the end of the file, this will
be more efficient than a blindly overwriting the cache."""
with open(user_file, 'r+') as f:
i = -1
last_pos = f.tell()
# enumerate is a generator, not complete list
for i, t in enumerate(readline_generator(f)):
if user_text[i] != t:
# rewind to the line before
# this diff was encountered
f.seek(last_pos)
# set the index back one in
# order to catch the change
i -= 1
break
last_pos = f.tell()
# then cut off remainder of file
f.truncate()
# recall that i is the index of the diff
# replace the rest of it with new
# (and potentially old) content
writelines(f, user_text[i+1:])
def blind_write_to_cache():
"""Blindly overwrite the cache with current text"""
with open(user_file, 'w') as f:
writelines(f, user_text)
def overwrite_user_text(i, text, save=False):
"""Overwrite a line of text
If `save` is True, then these changes are cached
"""
try:
user_text[i] = text
except IndexError:
raise IndexError("No text exists on line %r" % (i+1))
if save:
write_to_cache()
def user_input():
"""Get a new line from the user"""
return raw_input("input text: ")
def user_choice(msg, choices):
if len(choices) == 0:
raise ValueError("No choices were given")
ans = raw_input(msg)
if ans not in choices:
print("Invalid Response: '%s'" % ans)
m = "Respond with %s: " % _choice_repr(choices)
return user_choice(m, choices)
else:
return ans
def user_appends():
"""User adds a new line"""
user_text.append(user_input())
def user_reads(*args, **kwargs):
"""Print a set of lines for the user
Selects text via `user_text[slice(*args)]`
Use 'print_init' in kwargs to choose how
many lines are printed out before user must
scroll by pressing enter, or quit with 'q'."""
print_init = kwargs.get('print_init', 4)
sliced = user_text[slice(*args)]
if not isinstance(sliced, list):
sliced = [sliced]
for i, l in enumerate(sliced):
if i < print_init:
print(l)
sys.stdout.flush()
elif user_choice(l, ['', Quit]) == Quit:
break
def user_changes(i=None, save=False):
"""User changes a preexisting line"""
attempt = True
while i is None and attempt:
# get the line the user wants to change
i_text = raw_input("Line to be changed: ")
try:
# make user input an index
i = int(i_text)
except:
# check if they want to try again
c = user_choice("Bad input - '%s' is not an "
"integer. Try again? " % i_text, (Yes, No))
attempt = (c == Yes)
if attempt:
# user gave a valid integer for indexing
try:
user_reads(i-1)
overwrite_user_text(i-1, user_input(), save)
except Exception as e:
print("ERROR: %s" % e)
if user_choice("Try again? ", (Yes, No)):
user_changes(i, save)
# stores whatever text is already on
# file to `user_text` before use
read_from_cache()
cmds = ['time']
while True:
inp = input('::> ')
sinp = inp.split()
if str(sinp[0]) in cmds:
print('mkay.')
Would I be able to get the position of the item in the table, if the name and input match? Thanks!
UPDATE: Here's my updated code:
cmds = ['k', '1']
while True:
inp = input('>>> ')
sinp = inp.split()
try:
if str(sinp[0]) in cmds:
cmds.index(sinp)
print(sinp)
except ValueError:
print('Unknown Command')
It's returning me 'Unknown Command' whenever I type in k or 'k'. Same goes for 1, however '1' works. What's the reason for this?
Oh god. Sorry to trouble you guys, I did just sinp instead of sinp[0] for .index. ouch.
UPDATE: it's not accepting '1' or 1. even though it's in the cmds table.
You can use you_list.index(the_item)
cmds = ['time', 'yep']
while True:
inp = input('::> ')
sinp = inp.split()
if str(sinp[0]) in cmds:
print('mkay.')
print cmds.index(inp)
Output:
::> time
mkay.
0
::> yep
mkay.
1
::>
If cmds is the "table", then cmds.index gives you the position in which the matching string is.
The index() method of the list is what you need.
>>> cmds = ['e', 'r', 't']
>>> cmds.index('e')
0
>>> cmds.index('t')
2
>>> cmds.index('y')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 'y' is not in list
Make sure you put it in a try, except block in case the command is not found.
For example,
inp = str(input('::> '))
sinp = inp.split()
print("You are trying to run command:", sinp[0])
try:
print(cmds.index(sinp[0]))
except ValueError:
print("Command not recognised")