+1 (315) 557-6473 

Implement Frequency Reuse in Python Assignment Solution.


Instructions

Objective
Write a python assignment program to implement frequency reuse.

Requirements and Specifications

This is a program that clearly uses the function advantage of multiple reuse of code.
Implement a frequency reuse program with math functions.
Source Code
#!/usr/bin/python
from math import *
# import everything from Tkinter module
from tkinter import *
# Base class for Hexagon shape
class Hexagon(object):
 def __init__(self, parent, x, y, length, color, tags):
  self.parent = parent
  self.x = x
  self.y = y
  self.length = length
  self.color = color
  self.size = None
  self.tags = tags
  self.draw_hex()
 # draw one hexagon
 def draw_hex(self):
  start_x = self.x
  start_y = self.y
  angle = 60
  coords = []
  for i in range(6):
   end_x = start_x + self.length * cos(radians(angle * i))
   end_y = start_y + self.length * sin(radians(angle * i))
   coords.append([start_x, start_y])
   start_x = end_x
   start_y = end_y
  self.parent.create_polygon(coords[0][0],
        coords[0][1],
        coords[1][0],
        coords[1][1],
        coords[2][0],
        coords[2][1],
        coords[3][0],
        coords[3][1],
        coords[4][0],
        coords[4][1],
        coords[5][0],
        coords[5][1],
        fill=self.color,
        outline="black",
        tags=self.tags)
# class holds frequency reuse logic and related methods
class FrequencyReuse(Tk):
 CANVAS_WIDTH = 800
 CANVAS_HEIGHT = 650
 TOP_LEFT = (20, 20)
 BOTTOM_LEFT = (790, 560)
 TOP_RIGHT = (780, 20)
 BOTTOM_RIGHT = (780, 560)
 def __init__(self, cluster_size, columns=16, rows=10, edge_len=30):
  Tk.__init__(self)
  self.textbox = None
  self.curr_angle = 330
  self.first_click = True
  self.reset = False
  self.edge_len = edge_len
  self.cluster_size = cluster_size
  self.reuse_list = []
  self.all_selected = False
  self.curr_count = 0
  self.hexagons = []
  self.co_cell_endp = []
  self.reuse_xy = []
  self.canvas = Canvas(self,
       width=self.CANVAS_WIDTH,
       height=self.CANVAS_HEIGHT,
       bg="#4dd0e1")
  self.canvas.bind("", self.call_back)
  self.canvas.focus_set()
  self.canvas.bind('', self.resets)
  self.canvas.pack()
  self.title("Frequency reuse and co-channel selection")
  self.create_grid(16, 10)
  self.create_textbox()
  self.cluster_reuse_calc()
 # show lines joining all co-channel cells
 def show_lines(self):
  # center(x,y) of first hexagon
  approx_center = self.co_cell_endp[0]
  self.line_ids = []
  for k in range(1, len(self.co_cell_endp)):
   end_xx = (self.co_cell_endp[k])[0]
   end_yy = (self.co_cell_endp[k])[1]
   # move i^th steps
   l_id = self.canvas.create_line(approx_center[0], approx_center[1],
          end_xx, end_yy)
   if j == 0:
    self.line_ids.append(l_id)
    dist = 0
   elif i >= j and j != 0:
    self.line_ids.append(l_id)
    dist = j
    # rotate counter-clockwise and move j^th step
    l_id = self.canvas.create_line(
     end_xx, end_yy, end_xx + self.center_dist * dist *
     cos(radians(self.curr_angle - 60)),
     end_yy + self.center_dist * dist *
     sin(radians(self.curr_angle - 60)))
    self.line_ids.append(l_id)
   self.curr_angle -= 60
 def create_textbox(self):
  txt = Text(self.canvas,
    width=80,
    height=1,
    font=("Helvatica", 12),
    padx=10,
    pady=10)
  txt.tag_configure("center", justify="center")
  txt.insert("1.0", "Select a Hexagon")
  txt.tag_add("center", "1.0", "end")
  self.canvas.create_window((0, 600), anchor='w', window=txt)
  txt.config(state=DISABLED)
  self.textbox = txt
 def resets(self, event):
  if event.char == 'R':
   self.reset_grid()
 # clear hexagonal grid for new i/p
 def reset_grid(self, button_reset=False):
  self.first_click = True
  self.curr_angle = 330
  self.curr_count = 0
  self.co_cell_endp = []
  self.reuse_list = []
  for i in self.hexagons:
   self.canvas.itemconfigure(i.tags, fill=i.color)
  try:
   self.line_ids
  except AttributeError:
   pass
  else:
   for i in self.line_ids:
    self.canvas.after(0, self.canvas.delete, i)
   self.line_ids = []
  if button_reset:
   self.write_text("Select a Hexagon")
 # create a grid of Hexagons
 def create_grid(self, cols, rows):
  size = self.edge_len
  for c in range(cols):
   if c % 2 == 0:
    offset = 0
   else:
    offset = size * sqrt(3) / 2
   for r in range(rows):
    x = c * (self.edge_len * 1.5) + 50
    y = (r * (self.edge_len * sqrt(3))) + offset + 15
    hx = Hexagon(self.canvas, x, y, self.edge_len, "#fafafa",
       "{},{}".format(r, c))
    self.hexagons.append(hx)
 # calculate reuse distance, center distance and radius of the hexagon
 def cluster_reuse_calc(self):
  self.hex_radius = sqrt(3) / 2 * self.edge_len
  self.center_dist = sqrt(3) * self.hex_radius
  self.reuse_dist = self.hex_radius * sqrt(3 * self.cluster_size)
 def write_text(self, text):
  self.textbox.config(state=NORMAL)
  self.textbox.delete('1.0', END)
  self.textbox.insert('1.0', text, "center")
  self.textbox.config(state=DISABLED)
 #check if the co-channels are within visible canvas
 def is_within_bound(self, coords):
  if self.TOP_LEFT[0] < coords[0] < self.BOTTOM_RIGHT[0] \
  and self.TOP_RIGHT[1] < coords[1] < self.BOTTOM_RIGHT[1]:
   return True
  return False
 #gets called when user selects a hexagon
 #This function applies frequency reuse logic in order to
 #figure out the positions of the co-channels
 def call_back(self, evt):
  selected_hex_id = self.canvas.find_closest(evt.x, evt.y)[0]
  hexagon = self.hexagons[int(selected_hex_id - 1)]
  s_x, s_y = hexagon.x, hexagon.y
  approx_center = (s_x + 15, s_y + 25)
  if self.first_click:
   self.first_click = False
   self.write_text(
    """Now, select another hexagon such
    that it should be a co-cell of
    the original hexagon."""
   )
   self.co_cell_endp.append(approx_center)
   self.canvas.itemconfigure(hexagon.tags, fill="green")
   for _ in range(6):
    end_xx = approx_center[0] + self.center_dist * i * cos(
     radians(self.curr_angle))
    end_yy = approx_center[1] + self.center_dist * i * sin(
     radians(self.curr_angle))
    reuse_x = end_xx + (self.center_dist * j) * cos(
     radians(self.curr_angle - 60))
    reuse_y = end_yy + (self.center_dist * j) * sin(
     radians(self.curr_angle - 60))
    if not self.is_within_bound((reuse_x, reuse_y)):
     self.write_text(
      """co-cells are exceeding canvas boundary.
      Select cell in the center"""
     )
     self.reset_grid()
     break
    if j == 0:
     self.reuse_list.append(
      self.canvas.find_closest(end_xx, end_yy)[0])
    elif i >= j and j != 0:
     self.reuse_list.append(
      self.canvas.find_closest(reuse_x, reuse_y)[0])
    self.co_cell_endp.append((end_xx, end_yy))
    self.curr_angle -= 60
  else:
   curr = self.canvas.find_closest(s_x, s_y)[0]
   if curr in self.reuse_list:
    self.canvas.itemconfigure(hexagon.tags, fill="green")
    self.write_text("Correct! Cell {} is a co-cell.".format(
     hexagon.tags))
    if self.curr_count == len(self.reuse_list) - 1:
     self.write_text("Great! Press Shift-R to restart")
     self.show_lines()
    self.curr_count += 1
   else:
    self.write_text("Incorrect! Cell {} is not a co-cell.".format(
     hexagon.tags))
    self.canvas.itemconfigure(hexagon.tags, fill="red")
if __name__ == '__main__':
 print(
  """Enter i & j values. common (i,j) values are:
  (1,0), (1,1), (2,0), (2,1), (3,0), (2,2)"""
 )
 i = int(input("Enter i: "))
 j = int(input("Enter j: "))
 if i == 0 and j == 0:
  raise ValueError("i & j both cannot be zero")
 elif j > i:
  raise ValueError("value of j cannot be greater than i")
 else:
  N = (i**2 + i * j + j**2)
  print("N is {}".format(N))
 freqreuse = FrequencyReuse(cluster_size=N)
 freqreuse.mainloop()