Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
tuple index out of range
#1
Hello
I'm a coding newbie and first-time visitor to this forum. The script below throws the following error on execution:
Output:
File "detect.py", line 143 in <module> startTime.strftime("%I:%M%p"), totalSeconds) IndexError: tuple index out of range.
Any help would be appreciated.

delta1071

______________________________________________
# USAGE
# python detect.py --conf config/config.json

# import the necessary packages

from __future__ import print_function
from pyimagesearch.notifications import TwilioNotifier
from pyimagesearch.utils import Conf
from imutils.video import VideoStream
from imutils.io import TempFile
from datetime import datetime
from datetime import date
import numpy as np
import argparse
import imutils
import signal
import time
import cv2
import sys


# function to handle keyboard interrupt
def signal_handler(sig, frame):
	print("[INFO] You pressed `ctrl + c`! Closing mail detector" \
		" application...")
	sys.exit(0)

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-c", "--conf", required=True,
	help="Path to the input configuration file")
args = vars(ap.parse_args())

# load the configuration file and initialize the Twilio notifier
conf = Conf(args["conf"])
tn = TwilioNotifier(conf)

# initialize the flags for fridge open and notification sent
fridgeOpen = False
notifSent = False

# initialize the video stream and allow the camera sensor to warmup
print("[INFO] Warming up camera...")
# vs = VideoStream(src=0).start()
vs = VideoStream(usePiCamera=True).start()
time.sleep(2.0)

# signal trap to handle keyboard interrupt
signal.signal(signal.SIGINT, signal_handler)
print("[INFO] Press `ctrl + c` to exit, or 'q' to quit if you have" \
	" the display option on...")

# initialize the video writer and the frame dimensions (we'll set
# them as soon as we read the first frame from the video)
writer = None
W = None
H = None

# loop over the frames of the stream
while True:
	# grab both the next frame from the stream and the previous
	# refrigerator status
	frame = vs.read()
	fridgePrevOpen = fridgeOpen

	# quit if there was a problem grabbing a frame
	if frame is None:
		break

	# resize the frame and convert the frame to grayscale
	frame = imutils.resize(frame, width=200)
	gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

	# if the frame dimensions are empty, set them
	if W is None or H is None:
		(H, W) = frame.shape[:2]

	# calculate the average of all pixels where a higher mean
	# indicates that there is more light coming into the refrigerator
	mean = np.mean(gray)

	# determine if the refrigerator is currently open
	fridgeOpen = mean > conf["thresh"]

	# if the fridge is open and previously it was closed, it means
	# the fridge has been just opened
	if fridgeOpen and not fridgePrevOpen:
		# record the start time
		startTime = datetime.now()

		# create a temporary video file and initialize the video
		# writer object
		tempVideo = TempFile(ext=".mp4")
		writer = cv2.VideoWriter(tempVideo.path, 0x21, 30, (W, H),
			True)

	# if the fridge is open then there are 2 possibilities,
	# 1) it's left open for more than the *threshold* seconds.
	# 2) it's closed in less than or equal to the *threshold* seconds.
	elif fridgePrevOpen:
		# calculate the time different between the current time and
		# start time
		timeDiff = (datetime.now() - startTime).seconds

		# if the fridge is open and the time difference is greater
		# than threshold, then send a notification
		if fridgeOpen and timeDiff > conf["open_threshold_seconds"]:
			# if a notification has not been sent yet, then send a
			# notification
			if not notifSent:
				# build the message and send a notification
				msg = "Intruder has left your fridge open!"

				# release the video writer pointer and reset the
				# writer object
				writer.release()
				writer = None

				# send the message and the video to the owner and
				# set the notification sent flag
				tn.send(msg, tempVideo)
				notifSent = True

		# check to see if the fridge is closed
		elif not fridgeOpen:
			# if a notification has already been sent, then just set
			# the notifSent to false for the next iteration
			if notifSent:
				notifSent = False

			# if a notification has not been sent, then send a
			# notification
			else:
				# record the end time and calculate the total time in
				# seconds
				endTime = datetime.now()
				totalSeconds = (endTime - startTime).seconds
				dateOpened = date.today().strftime("%A, %B %d %Y")

				# build the message and send a notification
				msg = "Your fridge was opened on {} at {} " \
					"at {} for {} seconds.".format(dateOpened,
					[color=#F1C40F]startTime.strftime("%I:%M%p"), totalSeconds)[/color]

				# release the video writer pointer and reset the
				# writer object
				writer.release()
				writer = None

				# send the message and the video to the owner
				tn.send(msg, tempVideo)

	# check to see if we should write the frame to disk
	if writer is not None:
		writer.write(frame)

# check to see if we need to release the video writer pointer
if writer is not None:
	writer.release()

# cleanup the camera and close any open windows
cv2.destroyAllWindows()
vs.stop()
Reply
#2
First of all, try to isolate the problem, creating as small a piece of code that reproduces the problem. And post the code in tags without color enhancements, that really confused me for a bit.

The problem is that you have four sets of curly braces in your string, but you only pass three items to the format method. When format tries to fill in the fourth slot, it can't find anything to put there. It looks like you duplicated 'at {}' in your string, and should remove one of those.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
The error was indeed caused by the extra set of curly brackets. Thank you for your help and advice!
Reply
#4
Also i would advice start using f-string.
It look a lot better when curly brackets has the content,also easier to not make that error you get.
one = 1
two = 2
three = 3
four = 4

# .foramt() was new in Python 2.6
msg = "Your fridge was opened on {} at {} at {} for {} seconds.".format(one, two, three, four)

# f-string new in Python 3.6
msg_1 = f"Your fridge was opened on {one} at {two} at {three} for {four} seconds."
Output:
>>> msg 'Your fridge was opened on 1 at 2 at 3 for 4 seconds.' >>> msg_1 'Your fridge was opened on 1 at 2 at 3 for 4 seconds.'
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Thumbs Down I hate "List index out of range" Melen 20 3,295 May-14-2023, 06:43 AM
Last Post: deanhystad
Exclamation IndexError: Replacement index 2 out of range for positional args tuple - help? MrKnd94 2 6,271 Oct-14-2022, 09:57 PM
Last Post: MrKnd94
  IndexError: list index out of range dolac 4 1,886 Jul-25-2022, 03:42 PM
Last Post: deanhystad
  I'm getting a String index out of range error debian77 7 2,310 Jun-26-2022, 09:50 AM
Last Post: deanhystad
  IndexError: list index out of range Anldra12 2 1,431 May-03-2022, 01:39 PM
Last Post: Anldra12
  matplotlib x axis range goes over the set range Pedroski55 5 3,163 Nov-21-2021, 08:40 AM
Last Post: paul18fr
  IndexError: list index out of range rf_kartal 6 2,822 Sep-07-2021, 02:36 PM
Last Post: Larz60+
  Python Error List Index Out of Range abhi1vaishnav 3 2,285 Sep-03-2021, 08:40 PM
Last Post: abhi1vaishnav
  IndexError: list index out of range Laplace12 1 2,212 Jun-22-2021, 10:47 AM
Last Post: Yoriz
  IndexError: list index out of range brunolelli 11 6,466 Mar-25-2021, 11:36 PM
Last Post: brunolelli

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020