Opening a file based on user's input python - python

How to open a file from the list of given files based on the user's input which is an integer
print("Enter 1.tp.txt\n2.c17testpat.pat\n3.c432testpat.pat\n4.c499testpat.pat\n5.c1335testpat.pat\n6.c6228testpat.pat")
user = input("Enter a number")
if user == 1:
filename = "tp.txt"
elif user == 2:
filename = "c17testpat.pat"
elif user == 3:
filename = "c432testpat"
elif user == 4:
filename = "c499testpat.pat"
elif user == 5:
filename = "c1355testpat.pat"
elif user == 6:
filename = "c6288testpat.pat"
fp = open(filename)
is there any other way to do it in python
this caused NameError: name 'filename' is not defined

You could store the file list as a Python list, like so:
files = ["filename_1", "filename_2", "filename_3"]
Then to print them, you would use a for loop:
for i, s in enumerate(files): # Use enumerate because we need to know which element it was
print(str(i + 1) + ": "+ s) # i + 1 because lists start from 0
To make sure your input is a number, use a while loop that exits only if the input is a valid number:
while True:
inp = input()
if inp.isdigit():
filename = files[int(inp) - 1] # - 1 because lists start from 0
break
else:
print("Enter a number")
You'll still need to make sure the number is not too big (or small, for that matter).

probably because you need to convert user to int first (might be a string as written). Also you should probably finish with a default case to throw an error if the user inputs a non sensical value...

As the question indicates a strong will to learn coding and already tried something, I offer a variant that works for python version 3 (in version 2 one would need raw_input instead of input and a future import to declare the print function):
#! /usr/bin/env python3
import sys
names_known = ( # Hints 1 and 2
None, "tp.txt", "c17testpat.pat", "c432test.pat",
"c499testpat.pat", "c1355testpat.pat", "c6288testpat.pat")
options_map = dict(zip(range(len(names_known)), names_known)) # 3
print("Enter:")
for choice, name in enumerate(names_known[1:], start=1): # 4
print('%d.%s' % (choice, name))
user_choice = input("Enter a number") # 5
try: # 6
entry_index = int(user_choice)
except:
sys.exit("No integer given!")
if not entry_index or entry_index not in options_map: # 7
sys.exit("No filename matching %d" % (entry_index,))
with open(options_map[entry_index]) as f: # 8
# do something with f
pass
Many things still can go wrong, and any error will need the user to restart (no while loops etc.), but some achievements
Have the names only stored once (here I picked a tuple)
Keep the 1 as first number in user interface (insert dummy at index 0)
Derive a dict from the tuple storing the names (dict offers fast lookup)
Build the user interface info from the name tuple (ignoring the dummy)
Separate input from validation
Check domain type first (integer). If fails exit early via sys.exit and give info
Check domain membership otherwise exit with info
open the resource filename targets in a context block so you do not forget to close when done with the processing

Not python but worth to know how to use it via bash.
A simple bash sample that list a folder content and let's user choose the file by the index.
# menu.sh
# usage: bash menu.sh FOLDER
select FILENAME in $1/*;
do
case $FILENAME in
"$QUIT")
echo "Exiting."
break
;;
*)
echo "You picked $FILENAME ($REPLY)"
chmod go-rwx "$FILENAME"
;;
esac
done
Credit http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_06.html

Related

Error "invalid syntax" appears when trying to redirect using input/output in Python shell

I tried to practice input/output redirection in the Python shell. I have a file named SentinelValue.py which is where I have this code to add up the numbers in another file:
data = eval(input("Enter an integer (the input ends " + "if it is 0): "))
sum = 0
while data != 0:
sum += data
data = eval(input("Enter an integer (the input ends " + "if it is 0): "))
print("The sum is", sum)
The other file "Numbers.txt" contains numbers:
1
2
3
4
5
6
7
8
9
0
and my output.txt file is where I want the sum to show.
I tried using:
python SentinelValue.py < Numbers.txt > output.txt
but on shell, it highlights "SentinelValue" & says "invalid syntax".
I don't know why it's not working.
There are several things wrong with your code:
As already suggested in the comments, do not use eval() for a direct user input (or pretty much any time, in 99% cases when you think you need it - you don't!). A simple int() conversion should be more than enough without all the dangers of eval().
Connected with the previous, eval() evaluates the input. Further more, on Python 2.x input() itself does the evaluation (it's an equivalent of eval(raw_input())) so whenever it encounters an invalid input it will pop a SyntaxError.
Even if it doesn't pop a SyntaxError, it will most certainly pop a TypeError as eval() expects a string and it will receive an integer from the inner input().
You're printing the "Enter an integer..." prompt to STDOUT which will result it ending up in your output.txt (where you redirect the STDOUT).
You're shadowing the built-in sum() by using it as one of your variables. That's a bad practice that can lead to many problems and unexpected results down the line.
So, with all that in mind, here's how to rewrite it to address these issues:
# Let's first make sure it works on Python 2.x and 3.x by shadowing the input
try:
input = raw_input # on Python 2.x use raw_input instead of input
except NameError:
pass
result = 0 # tip: use a name that's not already built-in, like result
while True: # loop 'forever'...
data = input() # don't print anything when asking for input
try:
data = int(data) # don't print anything to STDOUT
if not data: # only if the integer is 0
break
result += data # add to the final result
except ValueError: # risen if the input is not an integer...
pass # so just ignore it
print("The sum is: " + str(result)) # finally, print the result

How can I have a string contained in a variable be put into an if statement as code in Python?

So here's what I'm trying to do:
The inputs will be in the correct syntax for Python. For example for this part:
conditionOne = input()
what the input will be something like "and 5 % 2 == 0"
So basically if conditionOne contains "and 5 % 2 == 0" and I have a statement which reads:
if exampleVariable == 1:
I need the program to get the string in the variable and put it into the if statement so it becomes
if exampleVariable == 1 and 5 % 2 ==0:
Is there any way to do this?
If I understand you correctly you can do something like this:
# Initializing
conditionTotal = 'exampleVariable == 1'
conditionOne = input()
# Updating
conditionTotal = conditionTotal + ' ' + conditionOne
# If you want to execute it
exampleVariable = 1
if eval(conditionTotal):
do_your_stuff()
But I wouldn't recommend you to code this way because you allow a user to enter any Python commands through the standard input that is completely unsafe because the user may execute an arbitrary Python program though yours.

How to take input from other programs

First program:
import destinations
import currency
main_function = True
while (main_function):
def main():
# Determine length of stay
while True:
try:
length_of_stay = int(input("And how many days will you be staying in " + destination + "? "))
# Check for non-positive input
if (length_of_stay <= 0):
print("Please enter a positive number of days.")
continue
except ValueError:
print("The value you entered is invalid. Only numerical values are valid.")
else:
break
Second program:
def get_choice():
# Get destination choice
while True:
try:
choice = int(input("Where would you like to go? "))
if (choice < 1 or choice > 3):
print("Please select a choice between 1 and 3.")
continue
except ValueError:
print("The value you entered is invalid. Only numerical values are valid.")
else:
return choice
choice = get_choice()
def get_info(choice):
# Use numeric choice to look up destination info
# Rates are listed in euros per day
# Choice 1: Rome at €45/day
if (choice == 1):
return "Rome", 45
# Choice 2: Berlin at €18/day
elif (choice == 2):
return "Berlin", 18
# Choice 3: Vienna, €34/day
elif (choice == 3):
return "Vienna", 34
destination = get_info(choice)
Problem: First program runs with an error after input:
"NameError: name 'destination' is not defined"
Question: How is it that adding destination = get_info(choice) doesn't count as defining destination ?
What can I do to get the first program to agree with the input from the second program?
import destinations will run the module with that name, which should be on the PythonPath (otherwise it will raise an ImportError). So that's good. Once that file is run, all variables, functions, classes that were defined in it are accessible under the namespace destinations.
So in the file called destinations.py, if there is a variable called destination (which you made on the last line of file2), then you can access it as destinations.destination from within the first file (or any file that has the import statement import destinations).
You can read up on the different ways of importing items from different modules over at effbot. It will teach you that another attractive alternative for you would've been to write
from destinations import destination
and then your first file will work normally.
Note that the code you've copied here seems to have some indentation issues. Furthermore, you'll want to write (in the first file) destination[0] each time you need the word ("Rome", "Berlin", ..), because your function get_info from the 2nd file (destinations.py), returns a tuple (e.g. ("Rome", 45). You'll get a TypeError if you don't take that into account.

I can't turn elements of my list into integers

I was tasked with the following
1. Design and write a program to simulate a bank. Your program should read account numbers, PINs,
and beginning balances from a text file. Each line of text in the input file will have all the information
about a single bank account - account number, PIN and beginning balance. All information fields are
separated by semi-colons. Here is some sample input:
516;5555;20000
148;2222;10000
179;9898;4500
My problem is I don't know how to turn these elements into integers I can manipulate such as were someone to withdraw money, here is what I have so far
def bank():
myfile = pickAFile()
file = open(myfile)
contents = file.readlines()
for i in range (0, len(contents)):
items = contents[i].split(";")
choice = requestInteger(" 1 - Withdraw, 2 - Deposit, 3 - Exit program ")
if (choice == 1):
PIN = requestInteger("Please enter your PIN")
if (PIN == items[1]):
print items[0]
print("Invalid PIN")
My if statements wont work though because everything in items is a string not an int, the language is JES which uses python syntax but java libraries
--- NEW ANSWER ---
Thanks for the feedback - you can use the same casting technique with a list comprehension.
items = [int(j) for j in contents[i].split(";")]
You could optionally surround it with a try/except block too, depending on how confident you are of the incoming data quality.
--- OLD ANSWER ---
You can cast it as an integer right after the requestInteger() call:
...
choice = requestInteger(...)
try:
choice = int(choice)
except ValueError:
# Spit some error message back
if (choice == 1):
...

Can't get my loop & match to append to correct list

I´m experiencing problems with my code.
I can´t get it to append to the list not_found as well as it loops twice for some reason.
Can anyone point me in the right direction? The match works for my_track, but it doesn't when it doesn't match.
# coding: utf-8
#!/usr/bin/env python
import spotimeta
import sys
import time
my_tracks = raw_input("Please enter a sentence: ").title().split()
playlist = []
real_playlist = []
not_found = []
def check_track(track_name, my_track, track_href):
if track_name == my_track:
playlist.append(track_href)
return 1
# make sure the user does not input a single word as input
if (len(my_tracks) > 1):
path = my_tracks[1]
else:
sys.exit("Invalid input, please enter a sentence.")
# let's search
for my_track in my_tracks:
match = 0
print "Searching for '%s'\n" % (my_track),
data = spotimeta.search_track(my_track)
for result in data['result']:
if not match == 1:
try:
match = check_track(result["name"],my_track,result["href"])
except Exception, e:
error = "not available"
else:
if data['total_results'] > 0:
not_found.append(my_track)
You should try debugging it. One of the simplest ways of debugging is add the lines:
import pdb
pdb.set_trace()
Then when you run the script it will stop at the set_trace line in the debugger.
Check out http://docs.python.org/library/pdb.html for more information.
From my understanding you're trying to do something like:
for my_track in my_tracks:
print "Searching for '%s'\n" % (my_track),
data = spotimeta.search_track(my_track)
for result in data['result']:
if result['name'] == my_track:
playlist.append(result['href'])
elif data['total_results'] > 0:
not_found.append(my_track)
Will this more or less work for you?
Please help me to understand.
Right off the bat, I'm noticing two things.
First, you're checking data['total_results'] a bit late; if the total results value is greater than zero (wait, what?), then you want to add it to the list immediately and move on without parsing the data. I would, after the call from spotimeta.search_track(), check to see if this is the data you don't want (then subsequently add it into the list).
Second, I'm confused about the intention of your for loop. If you're going through it to only find one item, then you can use the in statement (my_track in result).

Categories

Resources