Archive for ◊ July, 2011 ◊

Python is like music…
Wednesday, July 20th, 2011 | Author:

Sunt foarte amator în ceea ce privește muzica (nu mă refer la ascultat muzică :P ). Și dacă nu era de ajuns că încercam să cânt fără talent la chitară, mai nou încerc să învăț să cânt la pian. Dar dacă la chitară oricine poate să cânte ceva, la pian, aparent ai nevoie de ceva cunoștințe de teorie muzicală.

Și m-am apucat de acorduri la pian, bazându-mă pe ce știam la chitară. Dar cum ureche muzicală nu am, calculam pe hârtie care sunt notele echivalente între cele două instrumente.

Dar parcă nu era eficient… hai să aducem puțin geekyness în ecuație. Și la Python sunt amator, dar totuși sunt mai talentat în programare :P . Așa că hai să scriem niște generatoare de note și acorduri. Câteva zeci de minute mai târziu, “biblioteca” python de muzică de mai jos.

Așa că cine știe teorie muzicală și vrea să invețe python, sau cine știe python și vrea să vadă ce e acela un acord, să se uite pe pychords.

#!/usr/bin/python

def next_note(note):
# note can be A,B,C,D,E,F,G
	if note == 'G':
		return 'A'
	else:
		return chr(ord(note)+1)

def next_semitone(semitone):
# semitone can be A,A#,B,C,C# etc.
	if len(semitone)>1 :
		if semitone[1] == '#':
			return next_note(semitone[0])
	if semitone[0] == 'B':
		return 'C'
	if semitone[0] == 'E':
		return 'F'
	return semitone[0] + '#'

def next_nth_semitone(semitone, n):
	for i in range(n):
		semitone = next_semitone(semitone)
	return semitone

def next_pitch(pitch):
# pitch can be A0,A#0,C4 etc.
	if pitch[1] == '#':
		semitone = pitch[:2]
		octave = int(pitch[2:])
	else:
		semitone = pitch[0]
		octave = int(pitch[1:])
	semitone = next_semitone(semitone)
	if semitone == "C":
		octave = octave+1
	return semitone + str(octave)

def next_stream(init, function, size):
	stream = []
	for i in range(size):
		stream.append(init)
		init=function(init)
	return stream

def major_chord(note):
	print note+" chord:"
	print note,next_nth_semitone(note, 4),next_nth_semitone(note, 7)

def minor_chord(note):
	print note+"m chord:"
	print note,next_nth_semitone(note, 3),next_nth_semitone(note, 7)

# Guitar with standard tuning (fret 0 is open fret)
print next_stream("E4", next_pitch, 13)
print next_stream("B3", next_pitch, 13)
print next_stream("G3", next_pitch, 13)
print next_stream("D3", next_pitch, 13)
print next_stream("A2", next_pitch, 13)
print next_stream("E2", next_pitch, 13)

major_chord("A")
minor_chord("B")

Dacă am făcut ceva greșeli, commentariile sunt binevenite, cât timp sunt malițioase :P .

Și iată și rezultatul inițial dorit, și anume cum arată notele pe o chitară standard.

['E4', 'F4', 'F#4', 'G4', 'G#4', 'A4', 'A#4', 'B4', 'C5', 'C#5', 'D5', 'D#5', 'E5']
['B3', 'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'F#4', 'G4', 'G#4', 'A4', 'A#4', 'B4']
['G3', 'G#3', 'A3', 'A#3', 'B3', 'C4', 'C#4', 'D4', 'D#4', 'E4', 'F4', 'F#4', 'G4']
['D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3', 'A#3', 'B3', 'C4', 'C#4', 'D4']
['A2', 'A#2', 'B2', 'C3', 'C#3', 'D3', 'D#3', 'E3', 'F3', 'F#3', 'G3', 'G#3', 'A3']
['E2', 'F2', 'F#2', 'G2', 'G#2', 'A2', 'A#2', 'B2', 'C3', 'C#3', 'D3', 'D#3', 'E3']

Poate să calculeze și acordurile majore și minore:

A chord:
A C# E
Bm chord:
B D F#
RIP lab: Send RIP routes to remote neighbours
Tuesday, July 19th, 2011 | Author:

[Originally posted on ccielab.ro]

Scenario:
You have two routers running RIP, but the two routers aren’t directly connected because there is a third router between them. See topology below. How do you get routes across because RIP only communicates with routers that are directly connected?
riplab

The simple answer is to create a GRE tunnel between R1 and R3 so a tun interface simulates a direct connection of the two routers. But let’s take a more didactic approach to remember some things about RIP.

RIP v2 sends the updates to the address 224.0.0.9 that is a local multicast address (TTL=1). But there is another, very important in some situations (like some Frame Relay networks), way to send routes, and that is via unicast to a statically configured neighbor. Configuration is done via the neighbor command in the router rip configuration. The routes will be encapsulated in normal IP unicast packets and since RIP runs on top of UDP, they should be routed as any other packet.

R1:

interface Serial0/0/1
ip address 10.1.2.1 255.255.255.0
interface Loopback 0
ip address 192.168.0.1 255.255.255.0
router rip
version 2
passive-interface Loopback0
network 10.0.0.0
network 192.168.0.0

neighbor 10.2.3.3
no auto-summary

R3:

interface Serial0/0/1
ip address 10.2.3.3 255.255.255.0
interface Loopback 0
ip address 172.16.0.1 255.255.255.0
router rip
version 2
passive-interface Loopback0
network 10.0.0.0
network 172.16.0.0
neighbor 10.1.2.1
no auto-summary

You still need to have a network command for the interfaces when you send and receive the updates (in this case 10.0.0.0) otherwise the received updates will be ignored.

First thing you should be careful of is the fact that R1 and R3 need layer3 communication. So you do need static routes for the R1 and R3 routers through R2.

Having connectivity between each other, the router starts sending unicast packets with the routes. debug ip rip would show the following:

RIP: sending v2 update to 10.1.2.1 via Serial0/0/1 (10.2.3.3)
RIP: build update entries
172.16.0.0/24 via 0.0.0.0, metric 1, tag 0

Notice the update is sent to an unicast address and not 224.0.0.9.

Routes are received but they still are not in the routing tables. debug ip rip shows why:

RIP: ignored v2 update from bad source 10.2.3.3 on Serial0/0/1

This reminds us of how RIP works: if a router receives an update it checks to see if the source of the packet is on the same subnet as the IP configured on the interface. If they don’t match, the update is ignored. In our case, the source of the updates are not on the same network because R2 does not modify the packet source/destination in any way.

The solution to this is to disable the default mechanism with the no validate-update-source command in the router rip configuration. This way any updates will be accepted.

Here is a wanted route in the routing table of R3:

R 192.168.0.0/24 [120/1] via 10.1.2.1, 00:00:27

Notice that the next hop is not directly connected so it need to do a recursive lookup and use the static route to send it to R2 first.

S 10.1.2.1/32 [1/0] via 10.2.3.2