Duck typing - what about when you need a concrete type? - dynamic-languages

Say you are doing a calculator in a dynamic language (Python etc...) and you have an add method.
def Add(x, y)
print x + y
Now if you were to pass in anything but a number that would be wrong, so you need some datatype checking.
Is Duck Typing about objects as opposed to parameters like the above example?
Could anyone explain further?
Edit
By objects I mean:
Person.Quack()
Duck.Quack()
With no care about what gets passed into methods.

Duck typing is about not caring what the objects you're working with are as long as they support the necessary operations. So if + is string concatenation then passing strings to Add would be fine. If dates support the + operation then passing dates would be fine as well.

Related

python beginner : Dynamically modifying a python list with indexing/slicing to preform arithmetic operators [duplicate]

This question already has answers here:
Sum a list of numbers in Python
(26 answers)
Closed last month.
I have been stuck trying to write code that will dynamically take user input from a list and preform general arithmetic operators. In order to work around this I used indexing and slicing which did solve my problem temporarily but a new problem rose from doing this.
listgrades= []
num_students = int(input("How many students are you evaluating?"))
def student_info():
for i in range(0, num_students):
student_name=input("Enter your name here: ")
studnet_age=input("Enter your age here: ")
student_total_grade=int(float(input("What is your total grade")))
listgrades.append(student_total_grade)
student_info()
grades_sum= (listgrades[0] + listgrades[1] + listgrades[2]) / num_students
print(f"The average of all the student grades is {grades_sum}")
`
I'm trying to change the (listgrades[0] + listgrades[1] + listgrades[2]) to something more changeable, workable and scalable
I was trying to look and find a solution or a way to work around this but I hit a dead end and I ran out of ideas at this point.
I think a loop of some sorts might work for this but I'm not sure.
side note: I kinda looked into numpy and I can't use it since my school lab computers won't allow anything out of the default python module library.
I have some general advice and some specific suggestions.
For general advice, to see what built in methods are available is to use python itself.
At the command line type python3
then, within python type dir(list)
and you will see the available methods for lists.
You get more detailed information about any specific method by typing help and the class you are interested in followed by a dot, than the method name. For example help(list.count).
You can also type help(list) to get a more in depth list of all the functions and instructions for use. Type space to continue to the next screen, and b to backup a screen. Type q to end the help screens.
To exit python type exit()
More specifically, I agree that a loop would be a more dynamic direction to go, given you are asking how many students to evaluate in your input.
One way to loop through your list would be:
for x in listgrades:
sum = sum + x
Of course, you can perform other math operations inside the loop, or in similar loops. Presumably you will initialize your value before the loop.
At some point you may need to count how many grades are in your list. Fortunately, there's a built-in method for lists that gives you that information called count. You'll see this if you use python's dir(list) or help(list).
number_of_grades = listgrades.count
I think this will point you in the direction you were thinking with the code, without giving away much in exactly how, which is what you are learning. Best of luck!

Sympy: solve assuming variable is positive

I would like to solve an equation assuming the variable is positive. I try to use assuming construction like
from sympy.assumptions import assuming, Q, ask
from sympy.abc import x
with assuming(Q.positive(x)):
sol = solve(Eq(x**2, 4))
print(sol)
But such a construction still gives two roots: [-2,2]. On the other hand if I initially declare variable x as x = symbols('x', positive=True) the function solve works fine. How actually assuming works?
To understand the whole idea of the assuming function, let's take a look at some points:
Queries:
I like to interpret Q (assumption keys this page is about Predicates) as "Query" or "Question".
The Q attribute provides a lot of predicates that you can use to test boolean values and expressions. So it works indeed like question and answer.
Q.predicate(boolean) is for generating a Predicate object that can be evaluated with
True, False and None.
ask(boolean) provides the answer for the query (may be a Predicate object or other boolean).
The assuming function itself:
When you use the with statement and the assuming function, you are creating a context for querying. This means you are passing arguments to assuming and using them inside the body of the with statement.
It is comparable to creating a virtual environment, different from the base environment. There you can use the values passed to assuming as they were axioms, literally assuming that they are True.
Another important point is that when you create a query instantiating an object of Q, it is intuitively intended to use the ask function to determine the value of the Predicate object or expression.
Also, you may find an interesting reading about the old and new assumptions of SymPy here (this page is about the old assumptions).
I hope this was helpful!

Python Operator Overloading confusion

Please can someone provide some clarity on this python tutorial i have watched:
https://www.youtube.com/watch?v=BqF_r0FDgEc&list=PLS1QulWo1RIYt4e0WnBp-ZjCNq8X0FX0J&index=54
Around the 16 minute mark he's talking about using in built __str__() method. I
wanted to know the purpose of this method. Why would i use this instead of simply
creating my own method with a more meaningful name, for instance circle_area().
The only difference i can see is instead of being able to call it like this:
circle_area(c1)
I would have to call it like this:
c1.circle_area()
Also the main part of the tutorial is explaining the use of in built methods like __add__.
Instead of using that method i could instead do this to create c3:
c3 = Circle(c1.__radius + c2.__radius)
instead of this:
c3 = c1 + c2
I don't see the point of the in built methods he has mentioned. Is the only reason for using them because it would make programs look slightly neater?
Overloading a method allows you to define it for your specific use case of the objects.
If you overload __add__, you can use c1 + c2 instead of c1.__radius + c2.__radius.
The purpose? Neatness and abstraction. I'd definitely like c1 + c2 to work in my program. I'm adding two circle objects, I expect to get their radius added!
The video overloads and uses __str__ to print circle area =.
This same behaviour can be obtained with:
print("Circle area =", c1.area() )
The goal is to achieve abstraction instead of calling area method every time and printing the same thing.
May seem pointless when all you have is 20 lines of code, makes sense in a reality.
Overloading is definitely helpful in larger projects, and would seem a hassle in tiny ones. Tutorials are mostly tiny!

Type hinting a non-generator (non-consumable) iterable

I'd like to type hint a function like this:
from types import Iterable
def func(thing: Iterable[str]) -> None:
for i in range(10):
for x in thing:
do_thing(x)
PyCharm will (correctly) let me get away with passing in a generator to this function, but I want to type hint it in a way that it won't allow me to, while still accepting other iterables.
Using Sequence[str] isn't an option, iterables like KeyView aren't sequences, but I would still like to be able to include them.
Someone mentioned using a Union with a Sequence + KeyView, which would work, but I was wondering if there was a more elegant and universal solution
Of course, I could just convert thing to a list no matter what, but I'd rather just have this function type hinted correctly.
Using Python 3.7
Unfortunately I think this is just not possible with Python's type system.
Straight from Guido (source):
Our type system doesn't allow you to express that -- it's like asking for any Animal except Cat. Adding an "except" clause like that to the type system would be a very difficult operation.
Since there's no solution, I'm going to close this as "won't fix".
His suggestion:
Yeah, the practical solution is Sequence|Set|Mapping. The needed negation is years off.

What's the difference between T and def in groovy?

I was working with some SQL earlier that got me wondering what the difference was between these two typings.
In my example, I have 2 GroovyRowResults - pastData and currentData. Now, I need to compare 2 points from these result sets. These values should both be of indefinite type. So, when defining them, what's the difference between
def pastResult = pastData[commonKey]
def currentResult = currentData[commonKey]
if(pastResult == currentResult){
doSomething()
}
and
T pastResult = pastData[commonKey]
T currentResult = currentData[commonKey]
if(pastResult == currentResult){
doSomething()
}
I'm assuming T has been declared in your method/class earlier. In that case, it's a generic and the T refers to the same type of object consistently, whereas def is basically just an alias for Object.
T doesn't guarantee the two objects are the exact same class (they may just implement the same interface, or one may be a subclass), it does create more of a contract in the objects that you are dealing with. If you pass the same types of objects into the method, then there will be no difference, but if you pass different or unexpected types, it is more useful.
In other words, in Groovy it's done for readability and consistency, and using generics is much better than using dynamic typing.
I don't think the second example will work unless there is some kind of object called T. Check this link
http://groovy-lang.org/semantics.html#_variable_definition

Resources