I'm starting to learn Python and I find it really interesting. I am trying to create my own module and I ran into a bump. The code goes like this:
def break_words(sentence):
words = sentence.split(' ')
return words
def sort_words (words):
sort_word=sorted(words)
return sort_word
The second function has argument words fed in by the first, and I think it should work since it has been returned, but on running filename.sort_words(words) in Python, it gives an error message of NameError:global name 'words' is not defined. And it's requiring me to define words like words=filename.break_words(sentence) before it runs the second function.
What's wrong with my code?
You should try to explain yourself better in future, it's very confusing to read and probably the reason nobody replied.
This is what I think you want to know:
import filename
words = filename.break_words('some sentence goes here')
print filename.sort_words(words)
Have you tried that?
edit:
Variables in Python are always defined in scopes, so defining one variable in a function means that it is not defined anywhere outside the function.
'return' simply returns the value of that variable to the caller.
Related
I'm just starting to learn Python 3.9 as my first language. I have been fighting with this error for a while now, and I can't figure out what the issue is.
Here's what I'm working on:
def eval_express(eqstring[0], eqstring[1], eqstring[2]):
eqstring[0], eqstring[2] = float(eqstring[0]), float(eqstring[2])
return opdict[eqstring[1]](eqstring[0], eqstring[2])
I'm receiving an error that the "(" after eval_express is not closed, but as far as I can tell it is. At first, I thought it was just a glitch, but despite numerous attempts to rewrite it, increase/decrease the number of arguments, etc. it persisted. The error cropped up after I modified the arguments from variables to list items, but I don't see why that would affect it. Can anyone provide some clarification on what the program's getting hung up on?
Thank you for your help!
You are using square brackets inside the function parameters, which is not valid. Valid code would be:
def eval_express(eqstring0, eqstring1, eqstring2):
eqstring0, eqstring2 = float(eqstring0), float(eqstring2)
return opdict[eqstring1](eqstring0, eqstring2)
although you should probably use more descriptive parameter names.
You can't use parameter[] notation when entering a parameter to a function. Instead just use parameter, or you will have to do something like.
def eval_express(eqstring):
eqstring[0], eqstring[2] = float(eqstring[0]), float(eqstring[2])
return opdict[eqstring[1]](eqstring[0], eqstring[2])
Now you have to pass an array as the function parameter.
I am working to create a quiz on Python with different difficulty levels. I am trying to use functions so I can keep calling the most frequent part of the code, appending the questions into a list from an external text file.
However, I am running into a problem. When attempting to call my function I get the error:
NameError: name 'f' is not defined
I've tried everything I can think of but if anyone could provide any help, it would be greatly appreciated!
Here is the function:
def quiz(f):
f = open("quiz.txt", "r").read().split('\n')
for line in f:
f.append(questions)
f.close()
quiz(f)
print(questions)
The print(questions) bit is just a way for me to check if the lines have appended to the list.
When your code hits the line quiz(f), no f has been defined.
At that point in your code, only one thing has happened -- a function name quiz has been defined. That's the only identifier you can refer to at that point in your code.
You have declared function quiz to accept a parameter, but it makes no use of that parameter. The correct definition would be def quiz().
How can I avoid lines like:
this_long_variable_name = this_long_variable_name.replace('a', 'b')
I thought I could avoid it by making a function, repl,
def repl(myfind, myreplace, s):
s = s.replace(myfind, myreplace)
print(s) # for testing purposes
return s
but because of stuff about the local vs. global namespaces that I don't understand, I can't get the function to return a changed value for this_long_variable_name. Here's what I've tried:
this_long_variable_name = 'abbbc'
repl('b', 'x', this_long_variable_name)
print('after call to repl, this_long_variable_name =', this_long_variable_name)
The internal print statement shows the expected: axxxc
The print statement after the call to repl show the unchanged: abbbbc
Of course, it works if I give up and accept the redundant typing:
this_long_variable_name = repl('b', 'x', this_long_variable_name)
BTW, it's not just about the length of what has to be retyped, even if the variable's name were 'a,' I would not like retyping a = a.replace(...)
Since in the function s is a parameter, I can't do:
global s
I even tried:
this_long_variable_name.repl('b', 'x')
which shows you both how little I understand and how desperate I am.
The issue you're running into is that Python strings are immutable. str.replace() returns an entirely new string, so in s = s.replace(myfind, myreplace), the name s no longer refers to the original string, which is why you don't see any change on the outside of the function's namespace.
There probably isn't a great solution to your problem. I recommend using a modern IDE or Python REPL with autocompletion to alleviate it. Trying to abuse the standard way of writing things like this may feel good to you, but it will confuse anyone else looking at your code.
Harry it does not work because inside your repl function you actually have a local copy of the content of your this_long_variable_name. This is called "pass by copy" which means python hands over a copy to the function. Unfortunately this is how python does it. Check also here:
Python: How do I pass a string by reference?
Also strings are immutable in python so if you wanna change them you always create a new modified version. Check here:
Aren't Python strings immutable?
Question would be why should you need long variable names in the first place?
I'm super new to this and I'm trying to puzzle my way through is code and I'm stuck, I don't know how the program is referencing the lists I've copied/created. At the end it makes a new list called 'words'. I don't understand how 'words' is getting my previous lists inside of it.
'''
Making silly Sentences Game
'''
name = ['Bob', 'Rachel', 'Don']
verb = ['slaps', 'steals', 'jumps over']
noun = ['jello', 'car', 'U-571']
from random import randint
def pick (words):
num_words = len(words)
num_picked = randint(0, num_words -1)
word_picked = words[num_picked] **#THIS BIT HERE!!! How does it know what 'words' is?**
return word_picked
print (pick(name),pick(verb), 'a', pick(noun))
This is my first post so, I'm almost certain it's in the wrong place. Please be gentle.
This has to do with scope.
The line word_picked = words[num_picked] can "see" words because it is in the scope of the function pick(), which takes a single arguments words. So when you call pick(name), within the scope of pick(), words is now pointing to name.
It knows what words is because you told it.
When you did def pick(words) you defined a function which takes one argument, words. This means that whatever you pass as that argument will be available as words inside the function.
Now, when you called pick(name), you passed in the value name as the argument. So the value that was known as name is passed into the function, which receives it as words.
I need help with parameteres. Do both of these function definitions do the exact same thing for print_twice?
def print_twice(lol):
print lol
print lol
def print_twice(michael):
print michael
print michael
If yes, then I'm guessing the word used for the parameter doesn't matter, correct?
The word we use for the parameter does matter. It is important that the word you use:
is meaningful and clearly explains what the argument is for,
does not override some variable name from the external scope.
Importance of meaningful arguments' names
The name you use for argument is important, because the names of the arguments, their default values and the function name are the things developers using your function first see, even without the need to look into function documentation (eg. by using help(your_function)). Just use IDLE to define your function and then try to use it - when writing it, the IDLE will show you possible arguments.
So please, give them meaningful names that will make using your function easier and will not require looking into the documentation.
Overriding variables from outer scopes
When it comes to the second point, just look at this example:
def show_elements(elements):
"""Shows elements of the passed argument
"""
for element in elements:
print element
which works ok, but if you replace elements with eg. list, you will override list within this specific scope:
def show_elements(list):
"""Shows elements of the passed argument
"""
for element in list:
print element
and then if you would like to use list eg. for building a list, or converting from other type into list, then you will have problems. list is a builtin and you should not override it. Similar is true also about the other variables from the scopes surrounding the function.
Historically, when Python was resolving variable names by first looking into local scope, then global and builtin scopes, skipping all nonlocal ones (eg. scope from the function in which our function was defined), enclosing scope's variables were passed that way:
def funca():
local_val1 = 'some value1'
local_val2 = 'some value2'
def funcb(local_val1=local_val1):
# local_val1 is accessible here, even though local_val2 is not
...
...
But since the above is no longer true, you will need to take surrounding scopes into account, thus using non-conflicting name is important.
Yes they do. The name of a parameter is irrelevant, although good programming practices mandate that the name should be clear and self-explanatory
That's correct, the name of the parameter doesn't matter.
yes that is correct its just a variable name ...
That is correct. The word used for the parameter in the function definition is only a name, and does not refer to anything external.
Programming is supposed to be logical. So, let's think logically. If you write "a" on a paper twice, you get "a" two times. Same with "b." So you're doing the same function with letters. But what if you reassigned a value to a, each time a went through the function. I mean, what if a was a number, then IMO the closest you could get is something like this:
def func1(a, b):
a = input("Enter a number: ")
b = input("Enter another number: ")
b *= b
a *= a
print func1(a)
print func1(a)
print func1(b)
print func1(b)
Now, when I try to compile this specific code online, I get an error but I think something like this will work for the sake of trying to do what you're doing if done correctly? It's a good experiment, and I would imagine some usage in it.