Python Calculator with tkinter
To reduce duplication, look at what's identical in each line, and what's different. For the different parts, make them a part of a loop, or the arguments to a function. For the identical parts, make them the body of the function/loop. In this case, look at the lines:

Button(master, text="1", command=lambda: self.do_math(1)),
Button(master, text="2", command=lambda: self.do_math(2)),
Button(master, text="3", command=lambda: self.do_math(3)),


The only thing that differs are the text parameter values, and the argument to do_math. Conveniently, they're the same, so this can be a simple loop over a range of numbers. I'm going to use a list comprehension here:

self.number_buttons = [Button(master, text=str(n), command=lambda n: self.do_math(n))
                       for n in range(1, 10)]


And in most cases, that would be fine. Unfortunately though, you're needing to put n inside of a lambda, and that can cause some surprising problems. To fix it, I'm going to use the lambda n=n: . . . fix. If I didn't make this change, the text would be set fine, but each button would end up being passed 19 instead of the correct number.

self.number_buttons = [Button(master, text=str(n), command=lambda n=n: self.do_math(n))
                       for n in range(1, 10)]




modes also has some duplication that can be improved.

modes = {
    "+": self.sum + num,
    "-": self.sum - num,
    "*": self.sum * num,
    "/": self.sum / num
}

self.sum = modes[self.mode]


You're repeating self.sum and num over and over. You can just deal with the data later by mapping to functions instead of the sum. The operator module has functions that correspond to the common operators like + to make this easy:

import operator as op

mode_ops = {
    "+": op.add,
    "-": op.sub,
    "*": op.mul,
    "/": op.truediv
}

f = mode_ops[self.mode]
self.sum = f(self.sum, num)  # Now we only need to specify the data once


This also saves you from computing every possible answer ahead of time. If you ever added an expensive operator, this could save some overhead (although it would be unlikely that that would ever be a major problem).