Interpreter skips part of code in sys.argv - python-3.x

I have code in an if statement which checks if an argv was passed in the command line, however I have a part of code which should run if none argument was passed by the user (just the file name). Interpreter instead of running that code, instantly jumps to the code which should run if an argv was typed be the user and prints an IndexError: list index out of range.
import sys
if sys.argv[1] == '--list':
do sth
elif sys.argv[1] == '--remove':
do sth
else: (Which I thought will be ran with no arguments)
this part of code is skipped no matter what
How to make interpreter to run code in else statement if none argument was typed?

You are trying to access the element 1 of an array with length 1.
What you should do is to check for the length of the array and only after that try to access it.
import sys
if len(sys.argv) == 1:
# do something when no arguments are given
pass
else:
if sys.argv[1] == 'hi':
print("hi")

Related

How to write a simple test code to test a python program that has a function with two arguments?

I'm new in python, I have written a python program that reads a list of files and saves the total number of a particular character (ch) in a dictionary and then returns it.
The program works fine, now I'm trying to write a simple test code to test the program.
I tried with the following code,
def test_read_files():
assert read_files("H:\\SomeTextFiles\\zero-k.txt", 'k') == 0, "Should be 0"
if __name__ == "__main__":
test_read_files()
print("Everything passed")
I named the program as test_read_files.py
My python code is as follows:
# This function reads a list of files and saves number of
# a particular character (ch) in dictionary and returns it.
def read_files(filePaths, ch):
# dictionary for saing no of character's in each file
dictionary = {}
for filePath in filePaths:
try:
# using "with statement" with open() function
with open(filePath, "r") as file_object:
# read file content
fileContent = file_object.read()
dictionary[filePath] = fileContent.count(ch)
except Exception:
# handling exception
print('An Error with opening the file '+filePath)
dictionary[filePath] = -1
return dictionary
fileLists = ["H:\\SomeTextFiles\\16.txt", "H:\\SomeTextFiles\\Statement1.txt",
"H:\\SomeTextFiles\\zero-k.txt", "H:\\SomeTextFiles"]
print(read_files(fileLists, 'k'))
I named it as read_files.py
When I run the test code, getting an error: NameError: name 'read_files' is not defined
The program and the test code all are in the same folder (different than the python folder though).
Hopefully I am understanding this correctly, but if both of you python files:
test_read_files.py
read_files.py
Are in the same directory.. Then you should be able to just add at the top of the test_read_files.py the following import command:
from read_files import read_files
This will import the read_files function from your read_files.py script and that way you will be able to run it inside the other file.

Python: command line, sys.argv, "if __name__ == '__main__' "

I have a moderate amount of experience using Python in Jupyter but am pretty clueless about how to use the command line. I have this prompt for a homework assignment -- I understand how the algorithms work, but I don't know how to format everything so it works from the command line in the way that is specified.
The prompt:
Question 1: 80 points
Input: a text file that specifies a travel problem (see travel-input.txt
for the format) and a search algorithm
(more details are below).
python map.py [file] [search] should read
the travel problem from “file” and run the “search” algorithm to find
a solution. It will print the solution and its cost.
search is one of
[DFTS, DFGS, BFTS, BFGS, UCTS, UCGS, GBFTS, GBFGS, ASTS, ASGS]
Here is the template I was given:
from search import ... # TODO import the necessary classes and methods
import sys
if __name__ == '__main__':
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
# TODO implement
goal_node = ... # TODO call the appropriate search function with appropriate parameters
# Do not change the code below.
if goal_node is not None:
print("Solution path", goal_node.solution())
print("Solution cost", goal_node.path_cost)
else:
print("No solution was found.")
So as far as python map.py [file] [search] goes, 'file' refers to travel-input.txt and 'search' refers to one of DFTS, DFGS, BFTS,... etc - a user-specified choice. My questions:
Where do I put my search functions? Should they all just be back-to-back in the same block of code?
How do I get the command line to recognize each function from its four or five-letter code? Is it just the name of the function? If I call it just using those letters, how can the functions receive input?
Do I need to reference the input file anywhere in my code?
Does it matter where I save my files in order for them to be accessible from the command line - .py files, travel-input.txt, etc? I've tried accessing them from the command line, with no success.
Thanks for the help!
The function definitions go before the if __name__ == "__main__" block. To select the correct function you can put them in a dict and use the four-letter abbreviations as keys, i.e.
def dfts_search(...):
...
def dfgs_search(...):
....
...
if __name__ == "__main__":
input_file = sys.argv[1]
search_algo_str = sys.argv[2]
search_dict = {"DFTS": dfts_search, "DFGS": dfgs_search, ...}
try:
func = search_dict[search_algo_str]
result = func(...)
except KeyError:
print(f'{search_algo_str} is an unknown search algorithm')
Not sure what you mean by reference, but input_file already refers to the input file. You will need to write a function to read the file and process the contents.
The location of the files shouldn't matter too much. Putting everything in the same directory is probably easiest. In the command window, just cd to the directory where the files are located and run the script as described in the assignment.

Python code does not come out when first return statement is executed

enter image description hereI am a begineer in Python development and learning python on python 3.6
When I executed below code ,I expected it to terminate when first return statement is executed and I was expecting Output 4.
But It is iterating 3 times and giving output as 8.
As per my understanding as soon as return statement is executed it should come out of the function. Why this is not happening.
#!/bin/python3
def stockmax(prices):
# Write your code here
# Write your code here
count=0
profit=0
maximum=max(prices)
#print(maximum)
index_max=prices.index(maximum)
#print(index_max)
if len(prices)<=1:
return(profit)
else:
for i in range(len(prices)):
if i<index_max:
profit=profit-prices[i]
#print("profit if",profit)
count=count+1
#print("count is",count)
elif i==index_max:
#print(profit)
profit=profit+(prices[i]*count)
#print("profit elif",profit)
count=0
else:
profit=profit+stockmax(prices[i:])
return(profit) # should terminate on executing first return
x=(stockmax([5,4,3,4,5]))
print(x)
By calling stockmax inside of itself, you are opening up a new 'scope'. We can treat these as levels on a building. When you call it, you are essentially moving up a floor, or gaining a level. To get back to the ground floor, or the main 'scope' you need to go back through all of the lower floors. We can do this easily by using return a little bit sooner. In your code it would look a little like this:
def stockmax(prices):
count=0
profit=0
maximum=max(prices)
index_max=prices.index(maximum)
if len(prices)<=1:
return(profit)
else:
for i in range(len(prices)):
if i<index_max:
profit=profit-prices[i]
count=count+1
elif i==index_max:
profit=profit+(prices[i]*count)
count=0
else:
profit=profit+stockmax(prices[i:])
return(profit) # Use return here instead!
This would give us the desired output of 4.

can't assign to operator while using argparse

So i was trying to do project based on argparse. And actually I copied all the code down below from sentdex, who has a channel on Youtube.
But for some reason code of mine doesn't work and his does.
I'd be really happy if someone helped me, because it's so pissing off)
import argparse
import sys
def main():
parser=argparse.ArgumentParser()
parser.add_argument('--x', type=float,default=1.0,
help='What is the first number?')
parser.add_argument('--y', type=float,default=1.0,
help='What is the second number?')
parser.add_argument('--operation', type=str,default='sub',
help='What operation? (add, sub, )')
args=parser.parse_args()
sys.stdout.write(str(calc(args)))
def calc(args):
operation=args.operation
x = args.x
y = args.y
if operation == 'add':
return x + y
elif operation == 'sub':
return x - y
if __name__ =='__main__':
main()
#console:
--x=2 --y=4 --operation=sub
File "<ipython-input-1-f108b29d54dc>", line 1
--x=2 --y=4 --operation=sub
^
SyntaxError: can't assign to operator
argparse parses sys.argv, which is meant to be initialized from running the script in the command line, but you're running this from iPython, so it's treating sub as a built-in operator function.
You should either run this as a script from the command line, or modify args=parser.parse_args() to:
args=parser.parse_args(['--x', '2', '--y', '4', '--operation', 'sub'])
if you just want to test it without running the script from the command line.

how to pass many arguments through a command function (do_)

I want to code a simple command that could take 3 arguments for a text adventure game.
Basically at the prompt, I would type 'use key unlock door' and it would run a particular block.
Here is what I coded but it does not work:
def do_use(self, tool, action, object):
if tool == 'key':
if action == 'unlock':
if object == 'door':
print("seems like it works!")
else:
print("nope 1")
else:
print("nope 2")
else:
print("nope 3")
Notes: the rest of the commands work fine. I imported cmd
and the following is the main code:
class Game(cmd.Cmd):
def __init__(self):
cmd.Cmd.__init__(self)
....
if __name__ == "__main__":
g = Game()
g.cmdloop()
At the prompt, when I type:
>>> use key unlock door
I get the following error message:
TypeError: do_use() takes exactly 4 arguments (2 given)
The code would work if it would print:
seems like it works!
Any help will be appreciated.
Reading that documentation, it looks like all of the commands just take in a single string, and you have to parse the string yourself. Your command is defined as taking 4 arguments (including self), and cmd is calling it with self, input, which is 2. I think could get the result you want with the following:
def do_use(self, user_input):
args = user_input.split()
if len(args) != 3:
print "*** invalid number of arguments"
else:
tool, action, obj = args
# Do the rest of your code here

Resources