# Generators and yield

A source of confusion for a lot of people new to Python and for anyone who has not used them for a while is the yield keyword. As this must be the third time I’ve had to relearn generators I thought I’d make a few notes.

My way of visualizing a generator is a function that returns (or should that be generates?) an iterator. Having the yield keyword in a function is enough to turn it into a generator. Once you have called the generator to get the iterator you can use it as you would any other iterator. Jeff Knupp has a much fuller explanation on his blog so give it a read and then return.

For an example I created a Fibonacci number generator with the following code along with a few examples using an iterator.

```def fibonacci(a = 0,b = 1,maxiter=-1):
while True:
yield a
a,b = b,a+b
if maxiter > 0:
maxiter -= 1
if maxiter < 1:
return

print([f for f in fibonacci(maxiter=10)])
for f in fibonacci(3,5,20):
print(f)
```

First a few notes on the generator itself. You can specify the starting numbers a and b (naturally defaulting to 0 and 1) and a maximum number of Fibonacci numbers (or iterations to perform) with maxiter when you call the generator. Without setting maxiter the iterator will continue indefinitely and could not be used for list comprehension (the first example) and the for loop would be an infinite loop.

The use of return in a generator ends the iteration and is equivalent to raising a StopIteration exception (see PEP 255).  Replace the return keyword with `raise StopIteration `if you want to prove it.

Lastly, if you are wondering about the line a,b=b,a+b it is just a compact (and I think elegant) way of writing:

```temp = a + b
a = b
b = temp
```

Behind the scenes the loop is calling a next method to get the next value from the iterator. There is nothing to stop you manually calling the next method as shown below. Also the generator will create a new iterator each time it is called. Each iterator will encapsulate their own values for a, b and maxiter as shown below.

```i = fibonacci()
j = fibonacci(13,21)
print("variable i is %s\nvariable j is " % (i,j))
print("First 3 from i: %d , %d , %d" % (i.next(),i.next(),i.next()))
print("First 3 from j: %d , %d , %d" % (j.next(),j.next(),j.next()))
```

Hopefully Jeff’s explanation and my example above goes some way to explaining how generators work.

# Running SQL scripts

PowerShell has a very useful Invoke-SQLCmd cmdlet to run T-SQL scripts if you install the sqlps module. This module is installed as part of SQL Server Management Studio (SSMS) but you may not want to install the whole package just to run scripts. However you can install just the PowerShell module and a couple of dependencies.

First you need to download module and two dependencies. There are different versions for SQL 2012, 2014 and 2016 but all can manage instances of SQL Server back to 2000 (SQL Server 2000 must be running SP4 or later and SQL Server 2005 SP2 or later) so there is little reason not to just go with SQL 2016. You need the PowerShell Extensions for Microsoft SQL Server (PowerShellTools.msi) module plus the dependencies SQL Server Shared Management Objects (SharedManagementObjects.msi) and CLR Types for Microsoft SQL Server (SQLSysClrTypes.msi). All are available in both 32- and 64-bit depending upon which version of PowerShell you want to run.

Once downloaded you need to install the CLR Types first, following by the Shared Management Objects and then the PowerShell module. This can be automated with the following commands:

```msiexec /i SQLSysClrTypes.msi /qn
msiexec /i SharedManagementObjects.msi /qn
msiexec /i PowerShellTools.msi /qn```

Once installed you are ready to go. Later versions of PowerShell will implicitly import the module as needed. Earlier versions will need to add the line Import-Module sqlps

To quickly test everything is working, open a new PowerShell console window and enter the following

```Import-Module sqlps
Invoke-Sqlcmd -ServerInstance servername -Query "SELECT @@SERVERNAME"```

# WinError 10048

While testing a simple tornado app I managed to get a WinError 10048. The rest of the error message made no sense which is why I’ve made a note of it here.

Basically is was caused by the port I had tried binding to already being in use. In my case a previous run had failed to exit. When I tried to run the program again I got this message. A simple mistake and easy to fix.

If you do need to check what applications are listening on ports use the netstat command with as follows

`netstat -ab`