Code not returning anything

I have been writing a basic timekeeping code and for some reason it’s not returning anything.

Here is the dictionary and list I am using to store the values:

TimeVarList = ['millennium', 'centuries', 'decades', 'years', 'weeks', 'days', 'hours', 'minutes', 'seconds']
TimeList = {
	'millennium': {'Txt': 'millennium', 'Var': millennium, 'Limit': 9999, 'Next_Val': seconds},
	'centuries': {'Txt': 'centuries', 'Var': centuries, 'Limit': 10, 'Next_Val': millennium},
	'decades': {'Txt': 'decades', 'Var': decades, 'Limit': 10, 'Next_Val': centuries},
	'years': {'Txt': 'years', 'Var': years, 'Limit': 10, 'Next_Val': decades},
	'weeks': {'Txt': 'weeks', 'Var': weeks, 'Limit': 52, 'Next_Val': years},
	'days': {'Txt': 'days', 'Var': days, 'Limit': 7, 'Next_Val': weeks},
	'hours': {'Txt': 'hours', 'Var': hours, 'Limit': 24, 'Next_Val': days},
	'minutes': {'Txt': 'minutes', 'Var': minutes, 'Limit': 60, 'Next_Val': hours},
	'seconds': {'Txt': 'minutes', 'Var': seconds, 'Limit': 60, 'Next_Val': minutes},
}

And here is the code:

while True:
	for i in TimeVarList:
		if TimeList[i]['Var'] <= TimeList[i]['Limit']:
			TimeList[i]['Next_Val'] += 1
			TimeList[i]['Var'] = 0
		if TimeList[i]['Var'] != 0:
			print(TimeList[i]['Var'], TimeList[i]['Txt'])
			for j in TimeVarList[i : len(TimeVarList)+1]:
				if j != 0:
					Not_Zero = True
					break
				else:
					Not_Zero = False
	time.sleep(time_wait)
	seconds += time_wait
	TimeList['millennium']['Limit'] += 0.000000000000000000000000001

For whatever reason when I execute the code it won’t do anything and won’t allow other code to be typed. Why does this happen?

If the code doesn’t do anything, that means it remains stuck in the while True: loop, and never hits any print statements.

Which means you never satisfy the condition TimeList[i]['Var'] != 0.

When your code is stuck in a while True: loop, you can’t type new code. while True: means that it will keep running the code in that loop until it hits a break statement. while True is typically used precisely when you want something to run forever, or when you can guarantee that it will trigger a break statement eventually.


Some additional notes on your code:

	'millennium': {'Txt': 'millennium', 'Var': millennium, 'Limit': 9999, 'Next_Val': seconds},

it’s not clear where millennium has been defined.

TimeList = {

this is a dict not a list, so the name is confusing

	for i in TimeVarList:

prefer meaningful names, in this case:

	for unit_name in TimeVarList:
			for j in TimeVarList[i : len(TimeVarList)+1]:

remember, i is a string, such as 'millennium'. This is why you need meaningful names. If you’d ever hit this bit of code Python would have thrown an error.

	for i in TimeVarList:
		... TimeList[i] ...

looping over i and then only ever using TimeList[i] is an ugly construction.
Why not just loop over TimeList.values() directly? eg as:

	for time_thingy_dict in TimeList.values():
		if time_thingy_dict ['Var'] <= time_thingy_dict ['Limit']:
			time_thingy_dict ['Next_Val'] += 1
			time_thingy_dict ['Var'] = 0

which raises the question: why even use a dict of dicts if you’re just going to loop over the values in the dict? Why not instead use a list of dicts, so that you can loop over that?

1 Like

Hello,

you only have one break exit keyword in your loop script and it only affects the nearest loop which is the for loop. You don’t have a condition statement with a break keyword to exit the main while loop. This is why it never exits the main while loop.

Here is a test script highlighting this principle:

while True:

    try:
        response = int(input('What is a number? '))

        for num in range(1, response):

            print(num, end=' ')

            if num == 4:
                print('\n')
                break

    except KeyboardInterrupt:
        break

print('\nExited the while loop.')

To test this script, enter a number above the value of 4. Notice that it stops printing the values above 4 and immediately loops back to asking the original question but never actually exits the script. This is because break statements only apply to the nearest loop and not to all loops. You have to add a condition with a break keyword statement for each specific loop.

2 Likes

Ok, maybe I don’t understand but the lines that change the variables are in the while loop:

Please clarify if I am wrong on this.

P.S. Thank you for the additional pointers.

This is quite complicated, and also some of the code is absent. Something must set the variables referred to in the dictionaries: millenium, second, centuries, and so on, or you would have an error about that.

You should step through the loop in a debugger and see if it is doing what you hoped.

  1. If you’re using an IDE, there will be a nice, visual way of doing this.
  2. If you’re using something simpler (editor and Python at the command prompt, say), then there is pdb.
  3. If you don’t want to learn pdb then try a print(i, TimeList[i]['Var']) at the top of the i loop.
1 Like

I think I can see where your misunderstanding lies. But let me try to teach you how to debug.
How are you using Python? Spyder? Jupyter notebook? Interactive terminal? (I think I would recommend Spyder for beginners, but that’s not the only good option.)
You want to experiment with the individual lines of code, without running the whole loop. The great thing about Python (that distinguishes it from Rust, C, java, and many other languages) is that single lines or code can be run in isolation.
So, depending on your IDE, run TimeList or print(TimeList) or display(TimeList) to inspect what state that variable has. Do the same with millenium and seconds. Then run time.sleep(time_wait). (You may need to set time_wait first.) Inspect your variables again.
run seconds+=time_wait. Inspect your variables.
You have to understand what the individual lines of code do, and in Python the best way to find out is to play with them.
(You can examine what’s happening in you for loops and if statements by running things like for i in TimeVarList: print(i), print(TimeList[i]['Var'], TimeList[i]['Limit'], TimeList[i]['Var'] <= TimeList[i]['Limit']))

Here is the more polished version after some editation:

import time

mil_dict = {'Txt': 'millennium', 'Var': 0, 'Limit': 9999}
cent_dict = {'Txt': 'centuries', 'Var': 0, 'Limit': 10}
dec_dict = {'Txt': 'decades', 'Var': 0, 'Limit': 10}
year_dict = {'Txt': 'years', 'Var': 0, 'Limit': 10}
week_dict = {'Txt': 'weeks', 'Var': 0, 'Limit': 52}
day_dict = {'Txt': 'days', 'Var': 0, 'Limit': 7}
hour_dict = {'Txt': 'hours', 'Var': 0, 'Limit': 24}
minute_dict = {'Txt': 'minute', 'Var': 0, 'Limit': 60}
second_dict = {'Txt': 'second', 'Var': 0, 'Limit': 60}
Dict_list = [mil_dict, cent_dict, dec_dict, year_dict, week_dict, day_dict, hour_dict, minute_dict, second_dict]


def Timekeep(Dict_list, time_wait):
    while True:
        Not_Zero = False
        for i in Dict_list:
            if i['Var'] == i['Limit']:
                Next = Dict_list[Dict_list.index(i)-1]
                Next['Var'] += 1
                i['Var'] = 0
            if i['Var'] != 0:
                print(i['Var'], i['Txt'], end='')
                for j in Dict_list[Dict_list.index(i)+1 : len(Dict_list)]:
                    if j['Var'] != 0:
                        Not_Zero = True
                        break
                    else:
                        Not_Zero = False
                if i['Var'] > 1 and Not_Zero:
                    print('s, ', end='')
                elif i['Var'] > 1 and Not_Zero == False:
                    print('s. ', end='')
                elif i['Var'] == 1 and Not_Zero:
                    print(',  ', end='')
                elif i['Var'] == 1 and Not_Zero == False:
                    print('.  ', end='')
        time.sleep(time_wait)
        second_dict['Var'] += time_wait
        mil_dict['Limit'] += 0.000000000000000000000000001
        print('')


def Run():
    Timekeep(Dict_list, 1)

So now all you have to do is type:

Run()

To activate it.

It still has some weird things where it is not formatting the variables how I want it to with the Not_Zero variable but I’ll figure that out later.

Thanks all.