0

I am trying to write a heater function but I am having a few difficulties. I am fairly new to Python.

I want my heater to run for 15000 seconds but for the first 120 seconds (inclusive of 120) I want it to follow a linear path T = 0.0804 * t + 16.081 and then after 120 seconds I want it to remain constant for the rest of the remaining time at the final temperature found from the linear equation.

The code I have written is below which I am getting errors with

import math, numpy as np
from random import *

a = 0.0804
time = range(15001)

for time in xrange(15001):
   if 0 < = time < = 120:
     Temp = a * np.array(time) + 18.3
   elif time > 121:
     Temp = Temp[120]

Errors:

TypeError
Traceback (most recent call last)
  /Library/Python/2.7/site-packages/ipython-1.0.0_dev-py2.7.egg/IPython/utils/py3c‌​ompat.pyc in execfile(fname, *where)
      202 else:
      203 filename = fname
  --> 204 builtin.execfile(filename, *where)
/Users/mariepears/Desktop/heaterfunction.py in <module>
    () 16 print T
       17 elif t>121:
  ---> 18 T=T[120]
TypeError: 'int' object is not subscriptable`
  • 1
    well, what errors? (and I don't even know what to say about your variable names) – tckmn Aug 21 '13 at 14:01
  • Please edit it into the question so it's actually readable. – tckmn Aug 21 '13 at 14:04
  • @MariePears It would definitely improve readability if you would edit that into your question. – glglgl Aug 21 '13 at 14:04
  • 6
    `T[120]` is incorrect since `T` is a number, not a sequence. – Frédéric Hamidi Aug 21 '13 at 14:04
  • Please 1. Paste the error message into the post 2. Highlight it 3. Press CTRL+K, or click the two brackets at the top of the edit textbox, so we can make sense of the error message. – tckmn Aug 21 '13 at 14:06
  • 1
    So is T a t or A T or a T in a t? Answers on a postcard to WhyYouShouldNameYourVariablesProperly Inc at PO Box 52 – Tony Hopkinson Aug 21 '13 at 14:08
  • In the OP's defense, they are trying to port old scientific code to python, and the variable names in old scientific code are *never* clear. They usually are the single letter varaibles used in the corresponding math equations, hence `T` and `t`. Since this was actually a well-formed question with an actual code example by someone honestly trying to learn, let's give them a break and try to make SO a little more friendly. – SethMMorton Aug 21 '13 at 15:54

2 Answers2

3

It looks like you are getting muddled up between time (the range() result, so a list of integers) and Temp (uppercase, the loop variable, an integer).

time = range(15001)
for Temp in xrange(15001):
   if 0 <= Temp <= 120:
     Temp = a * np.array(time) + 18.3
   elif Temp > 121:
     Temp = time[120]

Because time is a list, you should not try to test against if it is smaller or greater than a single integer either; 0 <= time <= 120 makes no sense; ordering between different types always places numbers first, then orders them by type name; integers are always lower than lists, so time > 121 is always True.

temperatures = []
for second in xrange(121):
    last = a * second + 18.3
    temperatures.append(last)

temperatures += temperatures[120:] * (15000 - 120)

Or as a list comprehension:

temperatures = [a * min(sec, 120) + 18.3 for sec in xrange(150001)]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • I have re-edit my names. I want the time to loop and produce the different temperatures and then I want to hold the temperature constant after 120 seconds. – Marie Pears Aug 21 '13 at 14:16
  • 1
    @MariePears: then why not loop directly over `time`? – Martijn Pieters Aug 21 '13 at 14:22
  • @MariePears: what is the calculation per second supposed to *do*? The `np.array()` call makes no sense, really. – Martijn Pieters Aug 21 '13 at 14:27
  • Yes I want to loop over time I think maybe I should have for time in xrange? Sorry am a novice. – Marie Pears Aug 21 '13 at 14:34
  • I wanted to be able to multiply a list of values eg from 0 to 120 seconds by a value and thought I needed a numpy array to enable the multiplication? – Marie Pears Aug 21 '13 at 14:35
  • @MariePears: it is not clear what you expect the multiplication to be here. – Martijn Pieters Aug 21 '13 at 14:39
  • I have the equation Temp = 0.0804*time +18.3 and it is only true for the first 120 seconds of time. After that the temperature is constant. So I want to be able to loop through time between 0to120 to generate temperatures. How do I write this if not with a numpy array? – Marie Pears Aug 21 '13 at 16:28
  • See my latest version. – Martijn Pieters Aug 21 '13 at 16:38
  • If i wanted to get return the temperature each time it loops it is possible to write this without changing it completely? – Marie Pears Sep 09 '13 at 17:20
  • I am not certain what you mean; the code *collects* all the temperatures in a list. You can return only *once* from a function; are you looking for a generator instead? – Martijn Pieters Sep 09 '13 at 20:36
  • Yes I think I am looking for a generator instead. I have since realised that I need the temperature to be called each time not as a continuous list. Thanks for all the help – Marie Pears Sep 10 '13 at 11:15
  • @MariePears: use my `for` loop, replace `temperatures.append(last)` with `yield last` and you have a generator. – Martijn Pieters Sep 10 '13 at 11:21
  • import math, numpy as np from random import * a = 0.0804 temperatures = [] for second in xrange(121): last = a * second + 18.3 yield last temperatures += temperatures[120:] * (15000 - 120) It says 'yield' outside function – Marie Pears Sep 10 '13 at 14:10
  • @MariePears: if you wanted this to be a generator function, then you do need to put it in a *function*. See [The Python yield keyword explained](http://stackoverflow.com/q/231767) for more info on the `yield` keyword. – Martijn Pieters Sep 10 '13 at 14:16
  • a = 0.0804 def temperatures(): for second in xrange(121): last = a * second + 18.3 yield last mygenerator = temperatures() #create a generator print(mygenerator) for last in mygenerator: temperatures += temperatures[120:] * (15000 - 120) print(temperatures). It says that the error is 'function' object is not subscriptable. I am not sure which bit I am meant to be editing. Sorry am really struggling, even if this is easy – Marie Pears Oct 02 '13 at 14:32
  • Perhaps make this is a new question then? A generator function needs to be called first to produce the generator, but even then it is not going to be subscriptable; generators just produce one item after another, but once produced you cannot ask it for item 0 or item 1 or any other item in the sequence. – Martijn Pieters Oct 02 '13 at 14:41
0

In your loop, T is an integer from xrange(150001). In the then clause of your if statement, you set T to be an array, but that doesn't have anything to do with what happens in the elif clause.

In general, you should not reset the loop variable in the loop (and that's probably not what you mean to do).

In your edited version, you have Temp = Temp[120] which is no better: Temp is still not an array here, so you can't subscript it.

Andrew Jaffe
  • 26,554
  • 4
  • 50
  • 59
  • I put Temp=Temp[120] as I wanted the 120th position value to remain constant. I realise that it is probably wrong but I couldn't work out how to write what I wanted – Marie Pears Aug 21 '13 at 14:37