1

Ok, I'm having trouble with my very first program. If you look down to the two functions, what I want is for if the "cur" value is NOT between the min and max, for it to change the Target variable to "0" so I can use it latter in the program... But it doesn't seem to do it... Am I using "return" wrong? Basically, the functions need to turn target from 1 to 0, so that ri_fit changes to 0, so that my final if thingys trigger...

Sorry for the terrible code, I've only just begun!

#Clearance calculator
#clearances are in clearances.txt

targets = open("clearances.txt", "r")
lines = targets.readlines()   #get target clearances from file

in_min_target = float(lines[2])     #minimum intake clearance
in_max_target = float(lines[4])     #maximum intake clearance

ex_min_target = float(lines[8])    #miminum exhaust clearances
ex_max_target = float(lines[10])   #maximum exhaust clearances
targets.close

target_intake = (in_min_target + in_max_target) / 2     #find the ideal intake
target_exhaust = (ex_min_target + ex_max_target) / 2    #find the ideal exhaust

print "Intake Min: ", in_min_target
print "Intake Max: ", in_max_target
print "Exhaust Min: ", ex_min_target
print "Exhaust Max: ", ex_max_target
print """Target intake: %r
Target Exhaust: %r""" % (target_intake, target_exhaust)

print""
print "Enter current RIGHT side Intake clearance"
cur_r_in = float(raw_input(">"))
print ""
print "Enter current RIGHT side Exhaust clearance"
cur_r_ex = float(raw_input(">"))
print ""
print "Enter current LEFT side Intake clearance"
cur_l_in = float(raw_input(">"))
print ""
print "Enter current LEFT side Exhaust clearance"
cur_l_ex = float(raw_input(">"))


target = 1

def in_range(min, max, cur, valve, target):  #figures if intake valves are correct
    if min <= cur <= max:
        print "%r is in range." % valve
        target=1

    else:
        print "%r is OUT OF RANGE." %valve
        target=0

    return target

def ex_range(min, max, cur, valve, target):   #figures if exhaust valves are correct
    if min <= cur <= max:
        print "%r is in range." % valve
        target=1

    else:
        print "%r is OUT OF RANGE." %valve
        target=0
    return target


ri_fit = 1
re_fit = 1        #Assumes all valves are right, until further notice...
li_fit = 1
le_fit = 1

valve = "Right Intake"
print in_range(in_min_target, in_max_target, cur_r_in, valve, target)
print target
if target == 0:
    ri_fit = 0


print ""

valve = "Right Exhaust"
print ex_range(ex_min_target, ex_max_target, cur_r_ex, valve, target)

print ""

valve = "Left Intake"
print in_range(in_min_target, in_max_target, cur_l_in, valve, target)

print ""

valve = "Left Exhaust"
print ex_range(ex_min_target, ex_max_target, cur_l_ex, valve, target)

print ri_fit

if ri_fit==0:
    print "Right intake is out of range."
    print "Enter current right intake shim size."
    ri_cur_shim = int(raw_input(">"))

if re_fit==0:
    print "Right exhaust is out of range."
    print "Enter current right exhaust shim size."
    re_cur_shim = int(raw_input(">"))

if li_fit==0:
    print "Right intake is out of range."
    print "Enter current right intake shim size."
    li_cur_shim = int(raw_input(">"))

if le_fit==0:
    print "Right exhaust is out of range."
    print "Enter current right exhaust shim size."
    le_cur_shim = int(raw_input(">"))
Demonic
  • 55
  • 5
  • What's the difference between your two methods? The code for both looks exactly the same. – Makoto Dec 28 '12 at 02:18
  • Thank you all very much for your help. It now seems to work. It's really my fault for trying to do this before I really know what I'm doing! :) – Demonic Dec 28 '12 at 02:27

4 Answers4

2

When you assign to target inside one of your functions, you are replacing the value of the parameter named target in there, and not touching the global one. So if you want your functions to assign to the global target, you can't define a new target in the function.

But if you don't want to change your functions, you can use the fact that return returns a value (which you seem to understand, since you print it). If instead of printing it, you assigned it to target, then you'd get the value you want where you want it, and your function will work no matter where the value computed is ultimately destined to go.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
1

return returns a value from a function. You can store the result in a variable.

In your code, you're trying to pass target as a parameter and then set its value, but since integers are immutable, you won't be able to change target from within your function.

In your case, I'd change your code to something like this:

def ex_range(min, max, cur, valve):  # You don't need `target` here
    if min <= cur <= max:
        print "%r is in range." % valve
        target=1

    else:
        print "%r is OUT OF RANGE." %valve
        target=0
    return target

target = ex_range(...)  # Store the results in a variable

Better yet, use a boolean:

def ex_range(min, max, cur, valve):  # You don't need `target` here
    if min <= cur <= max:
        print "%r is in range." % valve
        return True

    else:
        print "%r is OUT OF RANGE." %valve
        return False
Blender
  • 289,723
  • 53
  • 439
  • 496
  • 1
    Why have the function (in the first version) assign to target AND return that value, to have the caller redundantly assign it to target? – Scott Hunter Dec 28 '12 at 02:13
  • @ScottHunter: `target` is within the function's scope, not the global scope, so it's just a matter of using two return statements versus one. – Blender Dec 28 '12 at 02:14
  • Ok, in the second example, what gets returned as `True` or `False`? How can I use that? – Demonic Dec 28 '12 at 02:15
  • @Demonic: `True` and `False` are keywords. You used `1` and `0`, but usually people use `True` and `False` instead, as they're more readable. – Blender Dec 28 '12 at 02:17
  • @Demonic: In your original code, `target=1` just set `target` to `1`. At the end of the function, you called `return target` to return the value of `target` from your function. `target` doesn't do anything other than hold the value of `1` or `0`. Since you `return` the value in the end, you can just skip the `target = ...` part and `return` the results immediately. – Blender Dec 28 '12 at 02:21
  • Ah, Ok. Well, I've turned "target" into a global value, so that seems to fix it. But I will keep your method in mind for next time, too! Thanks! – Demonic Dec 28 '12 at 02:28
  • @Demonic: Personally, I don't suggest you use globals for this. There's really no reason to. – Blender Dec 28 '12 at 02:32
  • @Blender, ok, but is there a good reason NOT to? I'm not being difficult, just honestly curious... – Demonic Dec 28 '12 at 02:33
1

I believe the issue lies in that you are passing target as a value, not as a reference. Within your functions, you should drop the target parameter, and instead write:

def ex_range(min, max, cur, valve):
    global target
    # ...
    # rest of your code

This way, the interpreter identifies that you're trying to set the global target variable, and not a local instance.

Otherwise, you could do something like:

def in_range(min, max, cur, valve):  #figures if intake valves are correct
    if min <= cur <= max:
        print "%r is in range." % valve
        return 1

    else:
        print "%r is OUT OF RANGE." %valve
        return 0

target = in_range(...) # fill in args
print target

See this related question.

Community
  • 1
  • 1
Lander
  • 3,369
  • 2
  • 37
  • 53
1

First, I guess you need () after close:

target.close()

Second: in_range and ex_range are exactly the same!

Third, anyway it is OK and so runs correctly:

in_range(1,10,7,'Right Intake',1)
in_range(1,10,17,'Right Intake',1)

output:

>>> 'Right Intake' is in range.
>>> 'Right Intake' is OUT OF RANGE.

So, it may be the arguments you are passing to functions are not OK! Check if you are reading them correctly from file.

Finally, avoid using min, max as arguments as they are built-in Python functions.

Developer
  • 8,258
  • 8
  • 49
  • 58