This is a part of my homework assignment and im close to the final answer but not quite yet. I need to write a function that writes the odd number between position 1 and 5 in a list.
I make something like that:
-in a file domain I write the condition for odd number:
def oddNumber(x):
"""
this instruction help us to write the odd numbers from the positions specificated
input: x-number
output:-True if the number is odd
-False otherwise
"""
if x % 2==1:
return True
else:
return False
-then the tests:
def testOdd_Number():
testOdd_Number=[0,1,2,3,4,5,6,7,8]
oddNumber(testOdd_Number,0,6)
assert (testOdd_Number==[1,3,5])
oddNumber(testOdd_Number,0,3)
assert (testOdd_Number==[3])
-and in the other file named userinterface I write this:
elif(cmd.startswith("odd from ", "")):
try:
cmd=cmd.replace("odd from ", "")
cmd=cmd.replace("to ", "")
i=int(cmd[:cmd.find(" ")])
j=int(cmd[cmd.find(" "):])
if (i>=len(NumberList) or i>j or j>=len(NumberList) or i<0 or j<0):
print("Invalid value(s).")
else:
for m in range(i-1,j):
if oddNumber(NumberList[m]):
print (NumberList[m])
except:
print("Error!")
-when I run the entire project(I have more requirements but the others one are good), and write odd from [pos] to [pos] it says me
Traceback (most recent call last):
File "C:\Users\Adina\My Documents\LiClipse Workspace\P1\userinterface.py", line 94, in <module>
run()
File "C:\Users\Adina\My Documents\LiClipse Workspace\P1\userinterface.py", line 77, in run
elif(cmd.startswith("odd from ", "")):
TypeError: slice indices must be integers or None or have an __index__ method
I've forgotten to say that I have a also a function main() where I print the requirements.Where am I wrong?
Python's string startswith method, described here:
https://docs.python.org/2/library/stdtypes.html
states that arguments are
some_string.startswith(prefix, beginning, end) #where beginning and end are optional integers
and You have provided prefix and empty string ( cmd.startswith("odd from ", "") )
Some things I noticed:
1) you can shorten your oddNumber function to
def oddNumber(x):
return x%2
2) in your tests, you rebind the functions name testOdd_Number to some list, then pass that around to your oddNumber function. is that the same function described above? Then it won't work, as this function expects a single integer to be passed.
Using the same name to refer to two different things is discouraged.
Actually, I have no idea what your testcode does or should do. Are you passing a list and expect oddNumber to modify it in place?
3) your custom command parser looks... odd, and fragile. Maybe invest in a real parser?
You should decouple command parsing and actual computation.
As brainovergrow pointed out, there is also your error, since .startswith does not accept a string as second argument.
Some general hints:
You can use list(range(9)) instead of hardcoding [0,1,2,3,4,5,6,7,8]
You can use filter to filter the odd numbers of a given list:>>> list(filter(oddNumber, range(9))) yields [1, 3, 5, 7].
You can also use list comprehensions: [x for x in range(9) if x%2] yields the same.
you might find any() and all() useful. Take a look at them.
Your naming scheme is neighter consistent nor pythonic. Read PEP8 for a style guide.
Related
I'm trying to find the maximum of any function f(x) in a certain range and in which x this happens. The arguments of the python function would be (f(x),[a,b]). f(x) being any function and [a,b] the range we will be studying.
For now I've tried a few things but none of them worked. The one I liked the most was a failure because of trying to convert a string onto a float.
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
result=float(function.replace("x",str(x)))
if result >= maxresult:
maxresult = result
maxresultx = x
return maxresult,maxresultx
print(maxf("x**2",[1,3]))
This one returns:
Traceback (most recent call last):
File "main.py", line 10, in <module>
print(maxf("x**2",[1,3]))
File "main.py", line 4, in maxf
result=float(function.replace("x",str(x)))
ValueError: could not convert string to float: '0**2'
I don't know if there is an easier way to do it or how to correct the code so that I can convert that string.
Your problem is that float() accepts a string that already represents a float (eg float("1.23"), not an expression that will result in one (eg float("2**3")). So, you must first evaluate the string.
float(eval("3**2"))
eval() will run any code contained in the string, so don't use it on code you don't trust.
Use this:
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
result=float(function(x))
if result >= maxresult:
maxresult = result
maxresultx = x
return maxresult,maxresultx
print(maxf(lambda x: x**2,[1,3]))
lambda defines a function (an anonymous one) that is passed as parameter, thus maxf can call it as needed.
Python is (also) a functional language, which means that you can use functions as you use ints or floats, etc. A function is just a bunch of callable code, you can associate an identifier to a function or not (just like int values referred by identifiers or as constant in code).
-----EDIT----- suggested by #bacjist
If you don't want to use lambda, then you may define the function as usual:
def f(x):
return x**2
and then call:
print(maxf(f,[1,3]))
The problem is your string is not actually being evaluated. It is just being converted to float so as the error suggests what you are doing is converting "0**2" to float which is not possible what you can do is make use of eval function to evaluate any given string and then compare the result.
You just need to make a small change like this:
result=eval(function.replace("x",str(x)))
This yet not the best way to do this you should use generator there:
def maxf(function,interval):
maxresult = 0
for x in range(interval[0]-1,interval[1]+1):
yield eval(function.replace("x",str(x))), x
print(max(maxf("x**2", [1, 3])))
A more pythonic approach would be using lambda with max function as a key
a_list = [1,3]
max_item = max(a_list, key=lambda x: eval("x**2"))
print(eval("x**2".replace("x", str(max_item))), max_item)
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 3 years ago.
i just can not understand the importance of return at the end of functions.with return u have to type print(function()) anyways so why cant we just type print(value) at the and of the function and when we need to use that function just call it like function()?
def example():
value = 5+5
print(value)
example()
print and return are not doing the same thing. The former is displaying information to the user, while the latter is giving a raw value out of a function. Consider the following:
>>> def print_10():
... print(10)
...
>>> def return_10():
... return 10
...
>>> print(return_10() + return_10())
20
>>> print(print_10() + print_10())
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'
return_10 gives back the number 10, while print_10 prints the value 10 to the console and returns None (since you don't specify a return value). Trying to use that value elsewhere is possible (None is a valid result), but it probably doesn't do what you want it to do.
Thinking of this in explicit typing makes this very clear:
def print_10() -> None:
print(10)
def return_10() -> int:
return 10
the print statement only prints what is inside the Parenthesis to the console to be seen and can't be stored in variables or do any operations on it as it is a NoneType
i will show you with an example:
def example():
a = 5
b = 6
print(a + b)
x = example() + 5
print(x)
the above code will return a TypeError.
but if you change it to this:
def example():
a = 5
b = 6
return(a + b)
x = example() + 5
print(x)
you get 16
if you want to display info and not use it again use print else use return
There's a principle called separation of concerns that proposes that each unit of code (function, class, module, etc.) should be responsible for doing just one thing (where the definition of "one thing" is flexible to account for the size of the unit of code being discussed). The benefit is that code that follows this principle is easier to test, debug, combine, and reuse.
If you write a function that prints its result, it is harder to reuse that code in situations where you don't want to print the result, but rather use it in some other way. The function is doing two things: calculating its result, and printing it. If you don't want it to do the second thing, or want it to do the second thing in a slightly different way, you are S.O.L. On the other hand, if the function just calculates its result, doing just one thing, the caller can easily print it if that's what they want.
That said, if you often find yourself printing a result, then it might make sense to provide a second function that calls the first and prints the result, especially if printing it is complicated. But having the first function available is a win for future code reuse.
Some development methodologies advise you to write the simplest thing that works. But I think preserving separation of concerns is an obvious and logical reason to ignore this advice in many cases.
Let me preface this by saying that I am fairly new to coding, so be gentle.
I have been writing the following:
def execute_move(player, house_choice, houses):
next_house=houses[house_choice]
chosen_house=houses[house_choice-1]
chosen_house_seeds=chosen_house[1]
for i in range(chosen_house_seeds):
if player=='P1': # skips the store of the opposite player
if next_house==houses[13]:
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
elif player=='P2':
if next_house==houses[6]:
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
[(next_house[0], (next_house[1]+1)) if x==next_house else x for x in houses]
next_house_index=houses.index(next_house)
new_nhi=next_house_index+1
next_house=houses[new_nhi]
[(chosen_house[0], (chosen_house[1]-chosen_house_seeds)) if x==chosen_house else x for x in houses]
return houses
My aim is to replace some of the tuples in the list 'houses', and then return the new list of tuples.
For some reason the var I assign the call to later on in the code only produces the original list when printed.
Im thinking that it may have something to do with the indentation of the 'if' statements or the indentation of the return statement.
Help much appreciated!
There is nothing intrinsically special about a return statement when compared to other Python statements.
As such, you should indent it as you would any other (i.e., by placing the return line inside the block that makes sense in your specific algorithm).
Any control structure (such as an if statement) expects the next line to be indented. The control structure ends when the code begins to go back to the original level
https://docs.python.org/3/reference/lexical_analysis.html#indentation
def function(input):
input = input * 2
if (input > 5):
input * 2
return input
input +1
return input
so in this case, if the input is < 2.5, it is returned doubled + 1. If it is >2.5 it is returned * 4
It is probably just a bad cut and paste, but the body of the function must be indented as well.
Your list comprehension statements, those that look like [(next_house[0], ...] are building lists but it's not assigned to anything so it is being discarded. Try setting result to a variable...
list_of_next_house_tuples = [(next_house[0], (next_house[1]+1)) if x==next_house else x for x in houses]
Then determine what you are going to do with this new list.
I'd like to see if it's possible to run through a list of functions in a function. The closest thing I could find is looping through an entire module. I only want to use a pre-selected list of functions.
Here's my original problem:
Given a string, check each letter to see if any of the 5 tests fulfill.
If a minimum of 1 letter passes a check, return True.
If all letters in the string fails the check, return False.
For each letter in the string, we will check these functions: isalnum(), isalpha(), isdigit(), islower(), isupper()
The result of each test should print to different lines.
Sample Input
qA2
Sample Output (must print to separate lines, True if at least one letter passes, or false is all letters fail each test):
True
True
True
True
True
I wrote this for one test. Of course I could just write 5 different sets of code but that seems ugly. Then I started wondering if I could just loop through all the tests they're asking for.
Code for just one test:
raw = 'asdfaa3fa'
counter = 0
for i in xrange(len(raw)):
if raw[i].isdigit() == True: ## This line is where I'd loop in diff func's
counter = 1
print True
break
if counter == 0:
print False
My fail attempt to run a loop with all the tests:
raw = 'asdfaa3fa'
lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]
counter = 0
for f in range(0,5):
for i in xrange(len(raw)):
if lst[f] == True: ## loop through f, which then loops through i
print lst[f]
counter = 1
print True
break
if counter == 0:
print False
So how do I fix this code to fulfill all the rules up there?
Using info from all the comments - this code fulfills the rules stated above, looping through each method dynamically as well.
raw = 'ABC'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
for func in functions:
print any(func(letter) for letter in raw)
getattr approach (I think this is called introspection method?)
raw = 'ABC'
meths = ['isalnum', 'isalpha', 'isdigit', 'islower', 'isupper']
for m in meths:
print any(getattr(c,m)() for c in raw)
List comprehension approach:
from __future__ import print_function ## Changing to Python 3 to use print in list comp
raw = 'ABC'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
solution = [print(func(raw)) for func in functions]
The way you are looping through a list of functions is slightly off. This would be a valid way to do it. The functions you need to store in the list are the generic string functions given by str.funcname. Once you have those list of functions, you can loop through them using a for loop, and just treat it like a normal function!
raw = 'asdfaa3fa'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper] # list of functions
for fn in functions: # iterate over list of functions, where the current function in the list is referred to as fn
for ch in raw: # for each character in the string raw
if fn(ch):
print(True)
break
Sample outputs:
Input Output
===================================
"qA2" -----> True True True True True
"asdfaa3fa" -----> True True True True
Also I notice you seem to use indexing for iteration which makes me feel like you might be coming from a language like C/C++. The for in loop construct is really powerful in python so I would read up on it (y).
Above is a more pythonic way to do this but just as a learning tool, I wrote a working version that matches how you tried to do it as much as possible to show you where you went wrong specifically. Here it is with comments:
raw = 'asdfaa3fa'
lst = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper] # notice youre treating the functions just like variables and aren't actually calling them. That is, you're writing str.isalpha instead of str.isalpha()
for f in range(0,5):
counter = 0
for i in xrange(len(raw)):
if lst[f](raw[i]) == True: # In your attempt, you were checking if lst[f]==True; lst[f] is a function so you are checking if a function == True. Instead, you need to pass an argument to lst[f](), in this case the ith character of raw, and check whether what that function evaluates to is true
print lst[f]
counter = 1
print True
break
if counter == 0:
print False
Okay, so the first question is easy enough. The simple way to do it is just do
def foo(raw):
for c in raw:
if c.isalpha(): return True
if c.isdigit(): return True
# the other cases
return False
Never neglect the simplest thing that could work.
Now, if you want to do it dynamically -- which is the magic keyword you probably needed, you want to apply something like this (cribbed from another question):
meths = [isalnum, isalpha, isdigit, islower, isupper]
for c in raw:
for m in meths:
getattr(c, m)()
Warning, this is untested code meant to give you the idea. The key notion here is that the methods of an object are attributes just like anything else, so, for example getattr("a", "isalpha")() does the following:
Uses getattr to search the attributes dictionary of "a" for a method named isalpha
Returns that method itself -- <function isalpha>
then invokes that method using the () which is the function application operator in Python.
See this example:
In [11]: getattr('a', 'isalpha')()
Out[11]: True
All the other answers are correct, but since you're a beginner, I want to point out the problem in your code:
lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]
First: Not sure which value i currently has in your code snipped, but it seems to point somewhere in the string - which results in single characters being evaluated, not the whole string raw.
Second: When you build your list, you are already calling the methods you want to insert, which has the effect that not the functions themself get inserted, but their return values (that's why you're seeing all those True values in your print statement).
Try changing your code as follows:
lst = [raw.isalnum, raw.isalpha, raw.isdigit, raw.islower, raw.isupper]
I'm going to guess that you're validating password complexity, and I'm also going to say that software which takes an input and says "False" and there's no indication why is user-hostile, so the most important thing is not "how to loop over nested char function code wizardry (*)" but "give good feedback", and suggest something more like:
raw = 'asdfaa3fa'
import re
def validate_password(password):
""" This function takes a password string, and validates it
against the complexity requirements from {wherever}
and returns True if it's complex enough, otherwise False """
if not re.search('\d', password):
print("Error: password needs to include at least one number")
return False
elif not re.search('[a-z]', password):
print("Error: password must include at least one lowercase letter")
return False
elif not re.search('[A-Z]', password):
print("Error: password must include at least one uppercase letter")
return False
print("Password is OK")
return True
validate_password(raw)
Try online at repl.it
And the regex searching checks ranges of characters and digits in one call, which is neater than a loop over characters.
(PS. your functions overlap; a string which has characters matching 'isupper', 'islower' and 'isnumeric' already has 'isadigit' and 'isalnum' covered. More interesting would be to handle characters like ! which are not upper, lower, digits or alnum).
(*) function wizardry like the other answers is normally exactly what I would answer, but there's so much of that already answered that I may as well answer the other way instead :P
To answer the original question:
raw = 'asdfa3fa'
functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
isanything = [func(raw) for func in functions]
print repr(isanything)
Since you are looping through a list of simple items and trying to find if all of the functions has any valid results, you can simply define the list of functions you want to call on the input and return that. Here is a rather pythonic example of what you are trying to achieve:
def checker(checks, value):
return all(any(check(r) for r in value) for check in checks)
Test it out:
>>> def checker(checks, value):
... return all(any(check(r) for r in value) for check in checks)
...
>>> checks = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
>>> checker(checks, 'abcdef123ABC')
True
>>> checker(checks, 'abcdef123')
False
>>>
You can use introspection to loop through all of an object's attributes, whether they be functions or some other type.
However you probably don't want to do that here, because str has lots of function attributes, and you're only interested in five of them. It's probably better to do as you did and just make a list of the five you want.
Also, you don't need to loop over each character of the string if you don't want to; those functions already look at the whole string.
Check out this one-line solution for your problem. That problem is from HackerRank. I loop through a list of functions using the built-in getattr function.
s='qA2'
[print(bool(list(filter(lambda x : getattr(x, func)(),s)))) for func in ['isalnum','isalpha','isdigit','islower','isupper']]
I'm watching the instructional videos on you youtube and started doing some of the exercises at http://code.google.com/edu/languages/google-python-class but I'm puzzled by the below problem in the string1.py file.
What I can't seem to understand is, what is the "s" in both_ends(s): doing?
# B. both_ends
# Given a string s, return a string made of the first 2
# and the last 2 chars of the original string,
# so 'spring' yields 'spng'. However, if the string length
# is less than 2, return instead the empty string.
def both_ends(s):
# +++your code here+++
# LAB(begin solution)
if len(s) < 2:
return ''
first2 = s[0:2]
last2 = s[-2:]
return first2 + last2
At the bottom of strings1.py there are some functions:
def main()
print 'both_ends'
test(both_ends('spring'), 'spng')
if __name__ == '__main__':
main()
So how does the program know to substitute "spring" for (s) or is that not what it's doing? I can post the entire file if need be. It's only 140 lines.
'spring' is the literal string passed as a parameter into function both_ends(), and 's' is the formal parameter to the function. Replacing a formal parameter with an actual parameter is performed when the function is called.
The 'test()' function is just there to confirm that the function behaves as expected.
When you call a function, the values you give the function are assigned to the corresponding arguments in the function header. In code:
def my_func(a): #function header; first argument is called a.
#a is not a string, but a variable.
print a #do something with the argument
my_func(20) #calling my_func with a value of 20. 20 is assigned to a in the
#body of the function.
s is a variable that we presume to hold a string. We pass 'spring' in through as a parameter.
s in def both_ends(s) is the parameter for the input string. The length of this string is checked with the call to len(s) < 2, and various characters in the string are accessed by position with s[0:2] and s[-2:]
See http://docs.python.org/tutorial/controlflow.html#defining-functions for specifics. Also the tutorial at http://docs.python.org/tutorial/index.html is pretty good - I mostly learnt from it.
s is the parameter to the function, but you plug in real strings like hello or world into the function instead of just the letter s. Think of it like a math function: you have f(x) = x + 5. When you plug in a number, say 2, you get f(2) = 2 + 5. That's exactly what happens with the both_ends function. To make it simpler, here's some code:
def f(x):
return x + 5
f(2)
The way you plug into the function in the code here is the same way you plug a string into your original function.