Open Side Menu Go to the Top
Register
Programming homework and newbie help thread Programming homework and newbie help thread

08-08-2016 , 09:37 PM
I'd think it would just have to be any subclass that was polymorphic to the argument, which includes the specific class
Programming homework and newbie help thread Quote
08-08-2016 , 09:46 PM
I'm completely new to programming and this subforum so please forgive me if this kind of newb question is inappropriate for this thread.

So I've been working through exercises out of the book Think Python 2 and haven't run into any problems until now. I created a function "do_twice" which repeats any given function twice. It has successfully repeated functions not involving a parameter twice but can't seem to successfully perform a function that involves a parameter.

For example, "do_twice" successfully performs the function "print_spam" twice when I input

do_twice(print_spam)

where "print_spam" is a simple print('spam') function.

"do_twice" is defined as

def do_twice(f):
(indent)f()
(indent)f()

However, if I try to use "do_twice" to repeat a function that involves a parameter, there seems to be a runtime error (wrong term?) where it only performs the function once and not twice.

For example, function "print_th3rd(s)" is defined to repeat any given string "s" 3x.

If I input do_twice(print_th3rd('bob')), it will repeat 'bob' 3x but then spit out an error message. I can't figure out why it isn't spitting out two 3x iterations of 'bob' and is instead only spitting out one 3x iteration then an error message.

Quote:
do_twice(print_th3rd('bob'))
bob
bob
bob
Traceback (most recent call last):
File "<pyshell#210>", line 1, in <module>
do_twice(print_th3rd('bob'))
File "<pyshell#200>", line 2, in do_twice
f()
TypeError: 'NoneType' object is not callable
>>>
What's happening here?
Programming homework and newbie help thread Quote
08-08-2016 , 10:12 PM
You need to redefine your function as:

def_do_twice(f, *a):
(indent)f(*a)
(indent)f(*a)

And the call would look like:

def_do_twice(print_th3rd, 'bob')

The *a passes in the unknown number of arguments (which could also be 0 arguments).

Last edited by Lattimer; 08-08-2016 at 10:25 PM.
Programming homework and newbie help thread Quote
08-08-2016 , 10:42 PM
Lattimer is right, but think about the reason why he's right.

You didn't do your first example like
do_twice(f())
you did
do_twice(f)
because f is sort of like a "pointer" to the function. But f() invokes the function and returns the result.

So when you say do_twice(print_th3rd('bob')) you're really saying "execute the function print_th3rd with the argument 'bob', and then pass the return value to do_twice.

The return value of print_th3rd is None (because you don't return anything) so in effect you are
1. running print_th3rd once
2. calling do_twice(None)
which gives the results you saw.

What Lattimer showed you is one solution. If you've covered lambdas, that's another
Programming homework and newbie help thread Quote
08-08-2016 , 11:06 PM
I forgot about lambdas, been a couple years since I've used python much. That's arguably a better way.
Programming homework and newbie help thread Quote
08-09-2016 , 04:11 PM
What you are writing is "pass a function with these arguments to a function, return the function"

Code:
def do_twice(f):
    f
    f
    
do_f(print("one"))
## which only evaluates once:
>>> one
This is happening because Python is calling the function and returning the immediate value, as python does not allow multiple return values.

Also, not sure what version of Python you are using, but as written, I'm getting this error in Python2.

Code:
    do_twice(print("one"))
                 ^
SyntaxError: invalid syntax
It can be done in Python3 though.
Programming homework and newbie help thread Quote
08-09-2016 , 05:34 PM
print isn't a function in python2
Programming homework and newbie help thread Quote
08-10-2016 , 12:31 AM
Ah, I thought they backported that. So it is just syntactically similar...

Code:
Python 2.7.12 (default, Jul 18 2016, 10:55:51) 
[GCC 6.1.1 20160621 (Red Hat 6.1.1-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> print("one")
one
... but not a function...

Code:
>>> dir(print)
  File "<stdin>", line 1
    dir(print)
            ^
SyntaxError: invalid syntax
while:

Code:
Python 3.5.1 (default, Jul 10 2016, 20:36:01) 
[GCC 6.1.1 20160621 (Red Hat 6.1.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> dir(print)
['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
 '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__',
 '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__',
 '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__',
 '__subclasshook__', '__text_signature__']
Huh... I had no idea until today. I don't use Python2 for anything, so I'll use that excuse!
Programming homework and newbie help thread Quote
08-10-2016 , 10:00 AM
It's super annoying. For example you can not give "lambda: print 'mything'" as a callback to something, because print isn't a function or expression. It's just, like, a reserved keyword.

Almost all the professional work I've found is python 2, mostly because 3 introduced some backwards incompatibilities that are fairly subtle, so any project started in 2 is difficult to port, and also I suppose not all libraries will work in 3 for the same reason. Seems like they kinda ****ed themselves there.
Programming homework and newbie help thread Quote
08-10-2016 , 10:39 AM
True.

There is one lib I use that are supposedly Python3 compatible, but it isn't until I go in and manually change the source code. These changes are mainly issues surrounding string-encoding and all the changes to dictionaries. 2to3 is more aggravating than useful, in my experience.

But I keep up with the good fight and just use Python3. I question the wisdom of this and wonder if I should just use Perl6 instead.
Programming homework and newbie help thread Quote
08-10-2016 , 10:40 AM
Anyone familiar with systemverilog? I'm having trouble with something and online searching isn't helping much.
Programming homework and newbie help thread Quote
08-10-2016 , 11:47 PM
never really played around with javascript, doing some now. I came across the following syntaxes and I'm not sure why one would be preferred.

Code:
function doThing(name) {
    return 'Hi, ' + name;
}

var bob = doThing('Bob');
console.log(bob);
Code:
var doThing = function(name) {
    return 'Hi, ' + name;
};

var bob = doThing('Bob');
console.log(bob);
I get that the second involves an anonymous function, but i'm not sure why I would pick that one.
Programming homework and newbie help thread Quote
08-11-2016 , 01:04 AM
Quote:
Originally Posted by Noodle Wazlib
never really played around with javascript, doing some now. I came across the following syntaxes and I'm not sure why one would be preferred.

Code:
function doThing(name) {
    return 'Hi, ' + name;
}

var bob = doThing('Bob');
console.log(bob);
Code:
var doThing = function(name) {
    return 'Hi, ' + name;
};

var bob = doThing('Bob');
console.log(bob);
I get that the second involves an anonymous function, but i'm not sure why I would pick that one.
The first example will get hoisted, the second example won't. What this means is that you can write.
Code:
var bob = doThing('Bob');
console.log(bob);
function doThing(name) {
    return 'Hi, ' + name;
}
This will work. But writing
Code:
var bob = doThing('Bob');
console.log(bob);
doThing = function (name) {
    return 'Hi, ' + name;
}
Will throw an error, doThing is undefined. I would argue that in both examples these are named functions, not anonymous functions. I prefer the first syntax because it follows the same syntax as initializing any other variable.
Programming homework and newbie help thread Quote
08-11-2016 , 01:18 AM
The hell does hoisted mean?
Programming homework and newbie help thread Quote
08-11-2016 , 01:44 AM
Not sure, but this looks similar to function pointers that are often used in callbacks where you a call back will take another function as an argument.
Programming homework and newbie help thread Quote
08-11-2016 , 02:11 AM
Hoisting means the variables and functions are lifted to the top of the local scope (or in the examples given, global scope), which is allowing the function with the argument bob to be defined, without error, despite being defined after the var bob.

Which allows this odd mess to happen:

Code:
var bob = doThing('Bob');

// call a function that isn't defined yet:
doThing(bob);

function doThing(name) {
    return 'Hi, ' + name;
}

// function call output:
--> "Hi, Hi, Bob"
here's another example (found online):

Code:
function printName() {
  console.log('Hello, ' + name);
  var name = 'Bob';
}

printName();
--> Hello, undefined
I'd love to know why anyone would use hoisting.
Programming homework and newbie help thread Quote
08-11-2016 , 07:37 AM
Quote:
Originally Posted by daveT
I'd love to know why anyone would use hoisting.
Function hoisting is one of my favorite features of javascript, though I'm not a fan of variable hoisting.

Function hoisting allows you to decouple source-code order and semantic order of functions. This allows you, eg, to aggressively use one-off helper functions, and then put them at the bottom of the file, perhaps under a comment that says "// implementation details below here" You can then read just the top of the file to understand everything meaningful about the program -- what it does at a high level.

Many languages have this feature, conceptually, just under a different name and in a limited context. Eg, in ruby and Java and almost any language supporting OO, you can define a class's methods in any order you want. This seems perfectly reasonable... after all, the concept of object methods has no natural notion of "order," and it shouldn't.

More generally, keep in mind it's a purely arbitrary implementation detail that programmers work inside text files that have a concept of up and down. Our real material is concepts.
Programming homework and newbie help thread Quote
08-11-2016 , 09:50 AM
Thanks a lot for the help Lattimer, Rusty, and dave. I redefined "do_twice" as Lattimer suggested and it indeed yielded the desired result. The book hasn't yet discussed "*a"/lambdas so I appreciate the headsup. I also appreciate the patient breakdown as to why the "do_twice" function as previously defined was only performing the called (correct term?) function once.

On a related note, are there any resources you guys would recommend for learning python? Think Python 2 has been helpful, but I'm starting to think videos might be more helpful.

FWIW, I've been working on a shell on my Mac which is running Python 3.5.2.
Programming homework and newbie help thread Quote
08-11-2016 , 11:06 AM
Quote:
Originally Posted by karamazonk
On a related note, are there any resources you guys would recommend for learning python? Think Python 2 has been helpful, but I'm starting to think videos might be more helpful.
As a total novice, I suspect you'd get more out of Learn Python the Hard Way than Think Python. It's more interactive, and learning programming is all about actually doing stuff (rather than just reading stuff).

I've also seen a lot of recommendations for MIT's intro to CS courses, which use Python as their primary language.
Programming homework and newbie help thread Quote
08-11-2016 , 11:59 AM
What about "Python for Informatics"? Free download on Amazon (and I believe elsewhere too), and it's used in Coursera's Python curriculum. PFI author based at least the first 10 chapters on Think Python except that he wanted the exercises to be "data oriented" instead of "number oriented", whatever that distinction means to him (yes, I'd like to be able to write programs that use data, and numbers too!).

I've worked through Learn Python the Hard Way up to the part where object-oriented Python is introduced, then lost interest for some reason (may have more to do with me than the text).

About Python 2 vs Python 3. I don't understand why this is such an issue. There's very little difference in how the code looks (different print statement, input() instead of raw_input() for getting user input, new integer division operator // in Python 3 while 1 / 2 evaluates to 0.5 instead of 0, can't recall much else). Run time performance is apparently not very different either? On my current setup (Mac), typing python at the command line gets me Python 2.7.10, while python3 gets me Python 3.5.2. I decided to switch to Python 3 for everything. Any reason not to? Other than using libraries that only work with Python 2, of course. What motivated me to make the switch was working with a library that supposedly worked with both, but inexplicably didn't work with Python 2 after all. Switching to Python 3 fixed that.
Programming homework and newbie help thread Quote
08-11-2016 , 12:40 PM
No reason to not start with Python 3 at this point, as far as I know.
Programming homework and newbie help thread Quote
08-11-2016 , 01:06 PM
Quote:
Originally Posted by Mossberg
No reason to not start with Python 3 at this point, as far as I know.
You may run into libraries that don't work. Stuff you see online may or may not work. The differences are quite subtle and hard to find.

http://python3porting.com/differences.html
Programming homework and newbie help thread Quote
08-11-2016 , 01:28 PM
Ok thanks, I'll use Python 3 except when using older libraries that don't work with 3. I recall Zed Shaw (author of LPTHW) being anti Py3 for reasons I didn't really understand, or maybe he never explained in the first place. Made me wonder if there was something fundamentally wrong with Py3.
Programming homework and newbie help thread Quote
08-11-2016 , 01:57 PM
Quote:
Originally Posted by gaming_mouse
Function hoisting is one of my favorite features of javascript, though I'm not a fan of variable hoisting.

Function hoisting allows you to decouple source-code order and semantic order of functions. This allows you, eg, to aggressively use one-off helper functions, and then put them at the bottom of the file, perhaps under a comment that says "// implementation details below here" You can then read just the top of the file to understand everything meaningful about the program -- what it does at a high level.

Many languages have this feature, conceptually, just under a different name and in a limited context. Eg, in ruby and Java and almost any language supporting OO, you can define a class's methods in any order you want. This seems perfectly reasonable... after all, the concept of object methods has no natural notion of "order," and it shouldn't.

More generally, keep in mind it's a purely arbitrary implementation detail that programmers work inside text files that have a concept of up and down. Our real material is concepts.
Well sure, classes are a property of the global space, and it makes sense that they can be defined anywhere.

There are ways to get function hoisting working in other languages, but I found, at least in my own code, that I used it more for circular references and I don't really mind the enforced ordering from no hoisting. Also, JS doesn't have namespaced files yet, right? Would you still put the one-off functions at the bottom if you could push all that to an external file?

Quote:
Originally Posted by JSLigon
Ok thanks, I'll use Python 3 except when using older libraries that don't work with 3. I recall Zed Shaw (author of LPTHW) being anti Py3 for reasons I didn't really understand, or maybe he never explained in the first place. Made me wonder if there was something fundamentally wrong with Py3.
LPTHW was written when Python3 first came out, and library support was dismal. If Django, NumPy, Pandas, etc aren't supporting Python3 at the time of the writing, then it makes sense to discourage using it for learning and greenfield projects

The entire reason for Python3 was character encoding, which broke backwards compatibility. The semantic changes were added to clean up issues, but they weren't the priority:

http://www.snarky.ca/why-python-3-exists
Programming homework and newbie help thread Quote
08-11-2016 , 02:01 PM
Quote:
Originally Posted by karamazonk
Thanks a lot for the help Lattimer, Rusty, and dave. I redefined "do_twice" as Lattimer suggested and it indeed yielded the desired result. The book hasn't yet discussed "*a"/lambdas so I appreciate the headsup. I also appreciate the patient breakdown as to why the "do_twice" function as previously defined was only performing the called (correct term?) function once.

On a related note, are there any resources you guys would recommend for learning python? Think Python 2 has been helpful, but I'm starting to think videos might be more helpful.

FWIW, I've been working on a shell on my Mac which is running Python 3.5.2.
I learned Python on Udacity. It's free, uses video lessons, and an interactive tool for submitting lesson work. I learned it to build a program with a website interface, and the courses also taught rendering it with HTML/CSS, so it was perfect for my needs.
Programming homework and newbie help thread Quote

      
m