I am new to Python and learning by myself.
This is my first post here, I appreciate any help that you can give me.
I have been trying to find the min value and the index on a list with a function.
This is the code that I wrote:
def findMin (L,startIndx):
m = L[startIndx]
index = startIndx
for i in range (startIndx,len(L)):
x = L[i]
if i < m:
i = index
m = x
else:
pass
return (m,index)
a,b = findMin([8,2,11,0,5])
print (a,b)
This is the error that I get:
**TypeError Traceback (most recent call last)
<ipython-input-33-9713029875a6> in <module>
----> 1 a,b = findMin([8,2,11,0,5])
2 print (a,b)
TypeError: findMin() missing 1 required positional argument: 'startIndx'**
I truly have no idea what is the problem with it, I appreciate any help,
The problem that you ran into is that you only passed one argument (L) and not the second one (startIndx) and you have some logic errors in your code as mentioned by other answers.
This is a much shorter way of writing your function using some built-in functions that isn't that error-prone.
Very compact form:
def findMin(L,startIndx=0):
m = min(L[startIndx:])
return (m, L.index(m))
Here is the more spaced out version of that function with some explenations.
#Notice that startIndx is a OPTIONAL ARGUMENT. This means if we don't pass anything to it, it will be defined to be 0
def findMin(L,startIndx=0):
#The searchspace is defined by SLICING the list using list[from:upto]
searchspace = L[startIndx:]
#Using the built-in min() function we find the smallest value in the list
m = min(searchspace)
#Then we use the built-in list.index(value) function to find the index of the smallest element
#Quick reminder: The first value in a list has the index 0
index = L.index(m)
#Finally we return the needed values
return (m, index)
This is how the function is called with startIndx:
test_list = [5,0,9,4,11]
test_index = 3
a,b = findMin(test_list, test_index)
print(a,b)
#--> 4, 3
When you call the function without the startIndx argument it searches through the entire list, because the optional argument startIndx is set to 0.
test_list = [5,0,9,4,11]
a,b = finMin(test_list)
print(a,b)
#--> 0, 2
So I can see a few errors in your algorithm.
First error:
findMin() missing 1 required positional argument: 'startIndx'
This error is due to the fact that findMin is a function that takes two arguments. First argument is the array you want to find the minimum of ([8,2,11,0,5] in your example). The second one is the startIndex. It is the index which you want to start at while searching for the min. You can add this index to your function call or add a default value in your funtion declaration.
Second error:
line 6: if i < m:
This is not what you want to do. Here you are comparing i (which is the current index of your for loop) and m which is the minimum value so far. You want to compare x and m like this:
if x < m
Third and last error:
i = index
This is wrong. You want to swap these two variables and assign i to index like this:
index = i
Here is the final correct code:
def findMin (L,startIndx):
m = L[startIndx]
index = startIndx
for i in range (startIndx+1,len(L)):
x = L[i]
if x < m:
index = i
m = x
else:
pass
return (m, index)
a,b = findMin([8,2,11,3,1], 0)
print (a,b)
Call with two parameters; findMin([8,2,11,0,5]) passes a single list. Perhaps findMin([8,2,11,0,5], 0).
Indentation appears to be incorrect, and this is critical in Python. All lines from "m =" to "return" must be indented one more level.
Variable naming could be improved; part of the confusion is likely from names like "m", "x", etc. What does m mean, vs. for example max_val?
Indexing seems confused; first you set index = startIndx then use for i. Delete the index = and use for index in range (startIndx + 1, len(L)) (you already have L[startIndx]).
What is the desired behavior and return value if startIndx is > len(L)?
Why comparing i to m?
Optimization: don't need the else: pass. It means "otherwise, do nothing" which does not need to be explicit.
findMin has two parameters, but you only pass it one argument. You have two choices:
Pass the argument that findMin requires.
a,b = findMin([8,2,11,0,5], 0)
Remove the startIndx parameter and use 0 instead:
def findMin (L):
index = 0
m = L[index]
for i in range (len(L)):
x = L[i]
if x < m:
index = i
m = x
else:
pass
return (m,index)
def findMin (L,startIndx): this function will expect 2 arguments L and startIndx. So you'll have to pass 2 arguments as well. But you are passing only 1 argument findMin([8,2,11,0,5]). [8,2,11,0,5] as a list is one argument passed to L, then missing one for startIndx which results in error.
startIndx seems unnecessary as well since all the elements needs to be traverse.
def findMin(L):
m = L[0]
index = 0
for i in range (1,len(L)):
if L[i]<m:
m=L[i]
index=i
return (m,index)
a,b = findMin([8,2,11,0,5])
print (a,b)
Related
value = 'bcdjbcdscv'
value = 'bcdvfdvdfvvdfvv'
value = 'bcvfdvdfvcdjbcdscv'
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
How to count the number of letters in a string with a list of sample? I get nothing in my python shell when I wrote the above code in my python file.
There is a built-in method for this:
value.count('c')
functions need to be called, and the return values need to be printed to the stdout:
In [984]: value = 'bcvfdvdfvcdjbcdscv'
In [985]: count_letters(value, 'b')
Out[985]: 2
In [987]: ds=count_letters(value, 'd') #if you assign the return value to some variable, print it out:
In [988]: print ds
4
EDIT:
On calculating the length of the string, use python builtin function len:
In [1024]: s='abcdefghij'
In [1025]: len(s)
Out[1025]: 10
You'd better google it with some keywords like "python get length of a string" before you ask on SO, it's much time saving :)
EDIT2:
How to calculate the length of several strings with one function call?
use var-positional parameter *args, which accepts an arbitrary sequence of positional arguments:
In [1048]: def get_lengths(*args):
...: return [len(i) for i in args]
In [1049]: get_lengths('abcd', 'efg', '1234567')
Out[1049]: [4, 3, 7]
First you should probably look at correct indenting and only send in value. Also value is being overwritten so the last one will be the actual reference.
Second you need to call the function that you have defined.
#value = 'bcdjbcdscv'
#value = 'bcdvfdvdfvvdfvv'
value = 'bcvfdvdfvcdjbcdscv'
def count_letters(word, char):
count = 0
for c in word:
if char == c:
count += 1
return count
x = count_letters(value, 'b')
print x
# 2
This should produce the result you are looking for. You could also just call:
print value.count('b')
# 2
In python, there is a built-in method to do this. Simply type:
value = 'bcdjbcdscv'
value.count('c')
def somefunction():
outputs = []
a = 0
while a < 100:
if a%2 == 0:
b = 2*a + 1
outputs.append(list(zip(a,b)))
a += 1
return outputs
The above code is not what i'm using exactly but produces the same error, why does the above code return:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
TypeError: zip argument #1 must support iteration
Is this a particularly efficient way of returning all the items within a function as one? If not, what is a better method?
It returns that error because of its exact error message; that is, the zip arguments must support iteration. You just have two numbers that you are trying to "store together". In that case, I'm assuming what you are looking for is the tuple data type. Either that or "put them together" with the list data type you already have. The zip is entirely unnecessary. I would suggest reading more about Python's built-in types.
Just get a list of tuples!! (or list if you prefer, but since you can't change tuples and you want to return all the outputs, tuples make more sense)
def somefunction():
outputs = []
a = 0
while a < 100:
if a%2 == 0:
b = 2*a + 1
tup = (a,b)
outputs.append(tup)
a += 1
return outputs
There is no need to use zip here, zip is for joining two lists together, you only have two integers so you can store them in a tuple and then append the tuple to outputs
when zip would work for this
Zip would work if you stored all as in a_list and all bs in b_list. Then you could do:
outputs.append(zip(a_list,b_list))
this is unnecessary because you can just append a and b together in a tuple to output just like my example. But that is how it would be done.
You can also use list comprehension in this case:
def f():
return [(x, 2*x + 1) for x in range(100) if x%2 == 0]
First, I have this function:
def change_pos(a, b):
temp = a
a = b
b = temp
print 'Done'
And I call it in another function but it just print 'Done' and do nothing.
I write the code directly:
a = 1
b = 2
temp = a
a = b
b = temp
It works fine. Any suggestion here?
Second, this is my code
def check_exception(list):
for element in list:
# Take list of numbers
# \s*: Skip space or not (\t\n\r\f\v), \d: Number [0-9]
# ?: Non-capturing version of regular parentheses
first = re.compile("\s*(?:\[)(\d+)\s*(?:,)").findall(element)
last = re.compile("\s*(?:,)(\d+)\s*(?:\])").findall(element)
# Convert string to integer
first_int = map(int, first)
last_int = map(int, last)
# Check and code above works
i = 0
print first_int[i]
change_pos(first_int[i],first_int[i+1])
print first_int[i+1]
print len(first_int)
#print type(first_int[0])
# Sort
# Error: list index out of range at line 47 and more
i = 0
while i < len(first_int):
if first_int[i] > first_int[i+1]:
change_pos(first_int[i], first_int[i+1])
change_pos(last_int[i], last_int[i+1])
i += 1
# Check exception
j = 0
while j < len(last_int):
if last_int[j] < first_int[j+1]:
return false
break
else:
j += 1
continue
return true
And I see: IndexError: list index out of range at conditions after # Error
Thanks for any help. :)
Your change_pos function does nothing useful as it only swaps the variables inside the function, not the variables that was used to call the function. One method of accomplishing what you want is this:
def change_pos(a, b):
print 'DONE'
return b, a
and then using it becomes:
a, b = change_pos(a,b)
Or even without a function:
a, b = b, a
Secondly, I'm sure you can figure out why you're getting an index error on your own. But here's why anyways. Arrays are zero indexed and you are using the length of last_int in your while loop. Now imagine last_int has a length of 5. That means it has index values ranging from 0-4. In the last iteration of the loop you are attempting to access last_int[5] in your if statement (last_int[j+1]) which of course will give you an index error.
You may have been told that variables are locations in memory with data in it. This is not true for Python. Variables are just names that point to objects.
Hence, you can not in Python write a function such as the change_pos function you attempt to write, because the names you change will be the names used in the function, not the names used when calling.
Instead of this:
a = 1
b = 2
change_pos(a, b)
You will have to do this:
a = 1
b = 2
a, b = change_pos(a, b)
The function needs to look like this:
def change_pos(a, b):
return b, a
This give you a hint that there is an easier way, and indeed there is. You can do this:
a = 1
b = 2
a, b = b, a
So no need for a function at all.
Since you actually want to swap integers in a list, you can make a function like this:
def change_pos(lst, p):
lst[p], lst[p+1] = lst[p+1], lst[p]
But I don't think that adds significantly the the readability of the code.
Also your usage of this is prefixed with the comment #sort. But your code does not sort. It's a bit like a half-assed bubble sort, but I don't know why you would want to do that.
Numbers are immutable in python. His when you pass them to a function, the function works with copies of the variables. This can be tricky if you try this with mutable types like Lists. But python has this function covered with some neat syntax tricks.
a, b = b, a
This swaps two variables with no need for any additional functions.
So I'm trying to learn Python using codecademy but I'm stuck. It's asking me to define a function that takes a list as an argument. This is the code I have:
# Write your function below!
def fizz_count(*x):
count = 0
for x in fizz_count:
if x == "fizz":
count += 1
return count
It's probably something stupid I've done wrong, but it keeps telling me to make sure the function only takes one parameter, "x". def fizz_count(x): doesn't work either though. What am I supposed to do here?
Edit: Thanks for the help everyone, I see what I was doing wrong now.
There are a handful of problems here:
You're trying to iterate over fizz_count. But fizz_count is your function. x is your passed-in argument. So it should be for x in x: (but see #3).
You're accepting one argument with *x. The * causes x to be a tuple of all arguments. If you only pass one, a list, then the list is x[0] and items of the list are x[0][0], x[0][1] and so on. Easier to just accept x.
You're using your argument, x, as the placeholder for items in your list when you iterate over it, which means after the loop, x no longer refers to the passed-in list, but to the last item of it. This would actually work in this case because you don't use x afterward, but for clarity it's better to use a different variable name.
Some of your variable names could be more descriptive.
Putting these together we get something like this:
def fizz_count(sequence):
count = 0
for item in sequence:
if item == "fizz":
count += 1
return count
I assume you're taking the long way 'round for learning porpoises, which don't swim so fast. A better way to write this might be:
def fizz_count(sequence):
return sum(item == "fizz" for item in sequence)
But in fact list has a count() method, as does tuple, so if you know for sure that your argument is a list or tuple (and not some other kind of sequence), you can just do:
def fizz_count(sequence):
return sequence.count("fizz")
In fact, that's so simple, you hardly need to write a function for it!
when you pass *x to a function, then x is a list. Do either
def function(x):
# x is a variable
...
function('foo') # pass a single variable
funciton(['foo', 'bar']) # pass a list, explicitly
or
def function(*args):
# args is a list of unspecified size
...
function('foo') # x is list of 1 element
function('foo', 'bar') # x is list with two elements
Your function isn't taking a list as an argument. *x expands to consume your passed arguments, so your function is expecting to be called like this:
f(1, 2, 3)
Not like this:
f([1, 2, 3])
Notice the lack of a list object in your first example. Get rid of the *, as you don't need it:
# Write your function below!
def fizz_count(lst):
count = 0
for elem in lst:
if elem == "fizz":
count += 1
return count
You can also just use list.count:
# Write your function below!
def fizz_count(lst):
return lst.count('fizz')
It must be a typo. You're trying to iterate over the function name.
try this:
def fizz_count(x):
counter = 0
for element in x:
if element == "fizz":
counter += 1
return counter
Try this:
# Write your function below!
def fizz_count(x):
count = 0
for i in x:
if i == "fizz":
count += 1
return count
Sample :
>>> fizz_count(['test','fizz','buzz'])
1
for i in x: will iterate through every elements of list x. Suggest you to read more here.
All right, I'm a novice at python, and here's the snippet of code in question:
<!-- language: lang-py -->
List = [["W","w"],["A","A"],["a","a"]]
def ascii():
x = 0
y = 0
aValues = [[],[],[]]
for item in List:
for item in List[x]:
c = "0"
c = ord(List[x[y]])
y = y + 1
aValues[x].append(c)
x = x + 1
return aValues
aValues = ascii()
print (aValues)
And, when I try to execute this, I get this error message:
>>>
Traceback (most recent call last):
File "/Users/Hersh/Desktop/Python/ascii_conversion.py", line 16, in <module>
aValues = ascii()
File "/Users/Hersh/Desktop/Python/ascii_conversion.py", line 10, in ascii
c = ord(List[x[y]])
TypeError: 'int' object is not subscriptable
>>>
What exactly is the problem, and how can I fix it?
As indicated in the error message, the erroneous line is
c = ord(List[x[y]])
x is an integer (like 0). Instead, you want:
c = ord(List[x][y])
i.e. take the x-th element of List (which is itself a list), and take the y-th element of that.
However, your method of iteration is very unpythonic. You never use the item variables, but you should. For example, a shorter way of writing the line is:
c = ord(item)
By using map and list comprehensions, you can cut down your code to:
def ascii():
return [map(ord, l) for l in List]
I'm not sure of what exactly you intend to do with the function, it has several errors. Try this and tell me if this is what you wanted:
List = [["W", "w"], ["A", "A"], ["a", "a"]]
aValues = [[ord(e1), ord(e2)] for e1, e2 in List]
print(aValues)
EDIT 1 :
Alternatively, if each sublist contains more than two elements, this version is better and will work for the general case:
aValues = [map(ord, pair) for pair in List]
EDIT 2 :
According to the comments, you need to use a function. All right, then let's implement the solution as a function - first thing, the input for the function should be received as a parameter, not as a global variable (List) as you have currently in your code. Then, the result will be returned, and I'll take the opportunity to show yet another way to solve the problem at hand:
def ascii(lst):
return [[ord(element) for element in pair] for pair in lst]
Use it like this:
List = [["W", "w"], ["A", "A"], ["a", "a"]]
ascii(List)
> [[87, 119], [65, 65], [97, 97]]
Hmm. Unfortunately you have quite a lot of issues here. They mostly stem from your misunderstanding of loops in Python.
When you do for item in List, item is set to each element in the list in turn. So, you can't then do for item in List[x] on the next line - that makes no sense. item is the inner list already - so you want to do for inner_item in item (or, call your outer list variable something more sensible).
The next two lines make no sense either. There's no point setting c to "0" then immediately setting it to something else. And don't forget, as I said above, you already have the item in the inner loop, which we've called inner_item. So your code should read c = ord(inner_item).
Hope this helps.
The correct way to index into a 2-dimensional list is not:
c = ord(List[x[y]])
But instead:
c = ord(List[x][y])
Your error comes from the fact that x[y] is an invalid sub-expression, because x is an integer and [] is the subscript operator. You cannot subscript an integer.
However, you don't actually need to index into your list to accomplish the same thing:
def ascii():
x = 0 ## redundant
y = 0 ## redundant
aValues = [[],[],[]]
for item in List:
for item in List[x]: ## you are reusing 'item', change the name here to 'subItem'
c = "0" ## redundant
c = ord(List[x[y]]) ## redundant, replace with: c = ord(subItem)
y = y + 1 ## redundant
aValues[x].append(c)
x = x + 1 ## redundant
Change line 10 to
c = ord(item)
x is not actually an array. It's an integer that you're incrementing.
You need to figure out what it is that you're trying to do, and look up the appropriate syntax for it. It's not very clear what x[y] is supposed to be representing.