The personal view on the IT world of Johan Louwers, specially focusing on Oracle technology, Linux and UNIX technology, programming languages and all kinds of nice and cool things happening in the IT world.

Sunday, May 31, 2009

A dictionary variable in Python is not that much different as a normal dictionary as you might have on your bookshelf. So first have a quick glimpse into the definition of a dictionary, accoording to wikipedia a dictionary is:

"A dictionary is a book or collection of words in a specific language, often listed alphabetically, with definitions, etymologies, pronunciations, and other information; or a book of words in one language with their equivalents in another, also known as a lexicon."

And this is somewhat the same as a dictionary variable we know in Python, it is a list with keys and a set of values. The keys are the index like the integer indices in a "normal" Python list variable. For example I want to make a dictionary containing all the employees per department like in the example below where you use the department name (dep0, dep1,.. in this case) as the key and the names of the people as the value. As you can see we first define the dictionary with a set of curly brackets. After that we define the key dep0 and the values attached to the key...than we take dep1.... dep2....

More likely you want to show something based upon a key like all the people in department zero. Which can be done with a statement like the one below:

>>> empPerDep["dep0"]('John', 'Carl', 'Vick')

And in a case like this you will almost certainly want to go even more deeper and define which part of it you want to show, for example you want to show only the employee Carl, this can be done with a statement like the one below:

>>> empPerDep["dep0"][1]'Carl'

This is all very usefull when you know what is where and you live in a very organized and structured world where everything is very predictable. However in normal world you will not be coding something is such a hardcoded way that if you want to print the name 'Carl' that you can hardcode empPerDep["dep0"][1] . You will have to make sure carl is in the dictionary and you have to find out where he is. We take a new example and use a phonebook application this time.

Now lets say we have to create a application around it, one of the things people will like to know is how many people in this university phonebook system are listed? You will be happy to see that also the len() function in Python will work on a dictionary.

>>> len(empPhoneBook)6

now lets say you want an option where you will be able to check who has been assigned a certain number. What you can do is a empPhoneBook[76435] where 76435 is the number you want to have more details about. This is a valid option and will work as long as 76435 is a key in your dictionary. If it is not your code will generate a very nasty error.

A better way to do this is to check before you try to retrieve. You can check if a key is in the dictionary by using the in option. This will give you a boolean back on which you can decide to try and retrieve the value.

>>> 12348 in empPhoneBookTrue>>> 76435 in empPhoneBookFalse>>>

Even do this is very useful you also want to do something like this the other way around. This is especially for a phonebook where you would like to search by name however the unique identifier is the phonenumber. So now we would like to know for example if "Colin Aitken" is in the dictionary so we do the following:

>>> "Colin Aitken" in empPhoneBookFalse

Surprisingly this is giving a false, this is because it is looking into the keys not into the values. So if we want to check if the name is in the values we have to use empPhoneBook.values() instead of empPhoneBook which will only take the keys in account.

>>> "Colin Aitken" in empPhoneBook.values()True

You will have to play around it little with dictionaries in Python to start loving them however when you do you will never give up that love to dictionaries again.

Saturday, May 30, 2009

Eric Schmidt, the CEO of Google is interviewed by Steve Pearlstein for the Washington Post Website. They discuss subjects like "Googzilla" and the Google culture and how this influences the way Google employees and managers work. Within Google it is sometimes seen that managers work for employees and not employees working for the manager. Because of the highly driven workforce they simply need managers to plan, take care of budgets and be some sort of firewall for internal politics while the employees can spend all the time on developing new systems and maintaing existing systems. A great way of working in my opinion which could very well be mixed with the new way of working you see on a rollout in for example the Netherlands at Microsoft and Capgemini for example.

BING is the name of the new search engine from Microsoft. However, even do mainstream media is referring to it as the new search engine on the block and the attempt of Microsoft to battle Google, it is not a search engine. Even Microsoft itself is stating that it is not a search engine.

Microsoft BING is a descission engine. When you enter a search criteria in Google it will return you the answer based upon a pagerank from ALL the public sources on the internet. When you enter a search criteria in BING it will return you the answers from all the sources that Microsoft thinks are valid.

In the video on decisionengine.com they state for example that on medical searches they will use the best information sources so that you never will get a opinion from lets say a 13 year old on the subject. Even do it sounds great at first you might want to think that over, "best information sources".... who decides what the best information sources are? In this case it is Microsoft and personlay I would like to have myself to be in controle. It means that Microsoft is controling what will end up in the searchresults where google is just giving math the controle of order it is diaplying it and the enduser (me) the option to decide what is valid in my opinion or not.

An other example what scares me, you can search for products, restaurants and such. On products you can even get a BING discount. I would not be supprised if Microsoft will get a fee for products sold via BING. Now the question is, what if would like to sell a product online and make it searchable via BING (like my results are visible Google) and I do not want to pay microsoft a fee. Will my product come up in a search, will it be at the bottom or will it handeld the same way as a product where Microsoft will make money?

Descision engine sounds great, however, I will stick to a search engine and be the judge myself what is valid or not. I do not want a corporation like Microsoft making the judgment on what I can read and can't read. Even do it sounds great at first it is limited and Microsoft is hoping it will be the new way to make "online money" becauase Microsoft is loosing lots and lots of money with its online services as can be seen in the chart below which I found at businessinsider.com. Where Yahoo, Google and such make lots of money Microsoft can't get it started. With BING I fear they missed it again.

Friday, May 29, 2009

Google announced a new product on the google IO conference named Google Wave. Google wave will be a new collaboration and communication system which enables user to start collaborating an new ways online. Working on documents with a group of people, editing stuff and communicating all in one platform. All I have seen until now looks very promising and as soon as I receive my account details from Google I will inform you about how it is working and what my first experiences are.

There are however some things in wave that might sound even more prommising. Even before the GO-LIFE of wave there are already API's available. This is not so strange because wave will be opensource and it will be using a open protocol which is developerd specialy for wave.

On waveprotocol.com you can find all the information you need about the new wave protocol from Google.

A second thing is the technolgy used which is quite prommising, Live Concurrent Editing is one of them and is explained by David Wang in the video below who is one of the developers of Google wave. Not only this technology is very usefull for google wave, you can use it for various situations where you will be able to use this approuche to solve problems where you have more than a single user working on the same data. It would be great to do some things with it in the future whenever a oppertunity comes along. I can advise everyone to have a look at the video below and take some time to look at other presentations about google wave.

Today I created a twitter account. I have been reading about twitter and hearing stories of people on the subject however never created a account. Someone I know has started to use twitter recently and because of this I wanted to give it a go. Looking into the way twitter works it looks like a blog only for very small messages.

it is not my intention to "twitter" everything like, getting coffee for the colleagues, getting lunch or things like that. It will be more like, working on ..... and stuff like that. Also new blogposts I have posted or working on will be twitterd. So if you follow my blog and do have a twitter account just add my twitter stream to it.

In the beginning I will be using twitter very often because it is new you will most likely however see that it will become less after some time and the messages might start to have more 'body'. Because I have installed twitter on my iPhone I will also be able to react and twitter on the go. I am really interested to see how this will go. For the couple of hours I am using twitter now I already learned that it can be very well used to expand you social network and it is a lot of fun.

Monday, May 25, 2009

When navigating within the HTML screens of Oracle E-Business Suite Release 12 you can come across the below error message about Stale Data. The message is really clear however I do get some questions about it every now and then. The problem is most likely that you have been using the back (or forward) button of your browser. The way the HTML code (Actually the JSP code) is setup is making it so that it can not handle this in some cases. You can try to get out of this by clicking more back and forward buttons however this will not make the page work as before. Best things to do is just close the page and return back to it from you forms session. If you are not coming from a forms sessions the best way is logout and login again to the system. This is until Oracle will solve this " Bug"

Error: Stale Data The requested page contains stale data. This error could have been caused through the use of the browser's navigation buttons (the browser Back button, for example). To proceed, please select the Close Window link at the top of the application page to return

Monday, May 18, 2009

As already discussed in a previous post you can use a tuple in Python. A tuple is in basic a list which content can not be changed. A tuple can have elements of all kind of variable types. This includes an other tuple. What this means is that a list can have a list as one of the list items, or a tuple because we handling tuples in this post.

this sounds useful however you have to keep track of what is nested and where it is nested. in the example below you can see how a tuple is nested in an other tuple. First we create a tuple named sometuple and after that we create a second tuple which as first element will have the tuple sometuple as a element.

now if we want the second element of the tuple which himself is a element of a tuple we can do this as followed:

print someothertuple[0][1]value1

As you can see this can become quite confusing when you start nesting a lot of tuples in tuples so in most cases this is not a good idea. However there are some situations where it can be used. Think about creating a static table which holds basic information about a chess board and what fields are black and which are white. You can calculate this also but you can also use nested tuples. You can also use it for example to create a layout for a playfield for a game... where can a player stand and where not. You have to remember that a tuple can NOT be updated so you can not use it to keep track of where a player is or how chess pieces are arranged. However for basic layout of your grid it can be used.

Thursday, May 14, 2009

As discussed in the previous post I discussed a little the min max planning of a item per subinventory in Oracle e-Business suite Release 12. You can set for a item the minimum and maximum stock level. Fast running items will have a bigger stock in most cases than items that you sell every now and then. Setting the correct minimum and maximum stock levels for a item can be a very challenging task. For large organizations it can involve datamining and some higher math, however I will not go into this in this post.

To make use of the minimum and maximum stock level settings defined for a subinventory within Oracle Inventory you can make use of the Min-max planning report. To start this report, or schedule it you have to go to you concurrent requests screen and start a new single request. The name of the concurrent request is "Min-max planning report". There are numerous parameters which can be set for this concurrent request.

Planning Level:planning level states if you want to run the report on organization level which will include all the subinventories of the organization or on a specific subinventory. If you pick the last you will have to define the subinventory.

Item selection:Here you can state the selection of the items you want to include in the report. You can pick all the items that have a current stock level below the minimum stock level, include only the items which have currently more stock than the max stock level or include all items.

Category set:You have to set a category set, by default it will be set for inventory item however a other item category for the items to be included on the min-max planning report can be chosen.

Item Category:Item category families and categories can be set to even more finely grain the selection of items you can set to be included in the final report.

Items from (to):A range of items can be set if you want a defined set of items. You can use this option to run the report only for a single item. In this case you define the same item number in the from and to field.

Planners:The same as can be done for items in the item from and item to fields can be done for the planners. You can run the report for a specific planner of group of planners.

Buyers:the same as can be done for items and planners can be done for buyers. You can run the report for a specific buyer or set of buyers. This can be very useful when you (as a buyer) want to run the report for the items you are responsible for.

Sort By:Sort by will influence the order of the items on the report. It can be set to Item, Category, Buyer or Planner.

Demand cutoff date:The report includes demand on or before this date. If you do not check Net Demand this calculation is for display purposes only. You can also set the offset for this date.

Supply cutoff date:The calculation for the includes open supply orders on or before this date.

Restock:Here you can state if you want to do a restock automatically based upon the outcome of the report. When you set it to yes the system will create requisitions. If you run the report on organization level it will also run make jobs for the items where you have stated it is a make item.

For Repetitive Items:"If you are using the Organization Planning Level, choose one of the following For Repetitive Item options: Create Requisitions for items under minimum quantity, Create Discrete Jobs for items under minimum quantity or run the Report Only without creating jobs or requisitions"

Default Delivery To:Default Delivery To enables you to set a default deliver to location. This is only used when you use the restock = yes option.

Net Unreserved Orders, Reserved Orders, WIP Demand:If set to yes the reserved, unreserved orders and the WIP demand will be subtracted from the total available stock on the given date so you will get a good indication what the stock will be on this given date and what the demand for restock will be on this date.

Include PO Supply, Move Order Supply, WIP supply, Interface:If set to yes the calculation will take in account the quantity which will be delivered for this date based upon purchase orders, move orders, WIP jobs and non-nettable subinventories.

Lot Control:here you will be able to state if items which are under lot control should be included in the report.

Display Format:Here you will be able to set the way the report is displayed and what it will contain.

Display Item Description:Include the item description in the report or not.

Wednesday, May 13, 2009

In this post I will be discussing the use of lists in Python. In a previous post I already discussed the use of a tuple, where a tuple is fixed a list is dynamic. When you define a tuple the content is set for the rest of the program, when you use a list instead you can change the content.

First start with defining a list variable and placing some data in the list, in this case it will be dutch names. As you can see in the example below we define a list almost the same as a tuple, the difference is the sort of brackets.

As can seen in the example above the variable type in Python can be checked with the type command. In this case we do a type(thelist) and we get a . Now if we want some things out of the list, for example we like to print the entire list we can do a print and the name of the list. However, in most cases you only want a part of the list displayed and not all the content of the list.

The same as we could do with a tuple is what we can do with a list in Python. See the example below:

As you can see you can do a listname[x] where listname is the name of your list variable and x is the number of the element in the list. Now in this case we use positive numbers because we will move in a positive direction. It might be that you do not want this so you can also use negative numbers like in the example below.

As you have been reading the blogpost on using a tuple in Python you might already expected it, you can also get parts of more than one element from a list. this is done via for example a [0:3] extension after the name of the list. This will slice your list and provide you the results.

However, there are more ways on slicing your list, like for example you can use negative numbers or only a endpoint or startpoint for the slice you want from the list.

When you play around with those options you will quickly learn how to get your data out of a list just the way you want it and just the way you need it. That is for the data that is in the list, as already stated you can modify the content of the list. You can for example add data to the list. In python we use for this basically 3 commands. append, insert and extend with all their own characteristics.

listname.append()append will add a given element to the end of the list so if we do a thelist.append("kees") this will be added at the end of the list. Remember, you can append also add a list variable to a list, this will not result in all the single elements of the list you append to be incorporated into the target list variable. It will add the given list variable to the list. If you want the single elements of a list to be added to a list and become elements of the target list variable you have to use the .extend() function for lists. A mistake quickly made, however only made once after you have been debugging for some time.

listname.insert(x,x)insert also will add a new element to the list however with the insert command you can define the location of the new element where append will always add it at the end. for example we can do a thelist.insert(2,"piet") will make sure that the new element piet will be at location 2 in the list. You can easily think of some situations where this can come in handy.

listname.extend([])The extend command will add a list to a list, in basic it will concatenate two lists into one which can be very handy in some situations where you build separate lists and finally have to combine the results. Think about parallel processing for example where in the end you will have to combine results to provide a complete overview. As shown in the example you can extend it with a list you build on the fly or a predefined list and just add the list variable as a extension on the list.

Even do it is important that you can remove elements from a list it is also important that you can remove items from a list. For this we have the list.remove command which enables you to remove a element from a list, you can see this in the example below:

The tricky part of removing a element from a list in Python is that if you try to remove a element which is not in the list it will give you a clean message, it will crash. So if you are writing some code it is a good thing to check first if the element is (still) in the list. This can be done by using a "in" command. for example if you want to be sure that element a is in the list you do a "a" in listwherelist is the name of your list and a the value to be removed. This will return a boolean value upon which you can decide to execute the remove or not.

Monday, May 11, 2009

When you are deploying a Oracle E-Business Suite instance in a major enterprise, or a company with many different locations you most likely will have to spend some time on sourcing. In cases a company has only 1 or 2 warehouses you will have a simple task. items are purchased from a supplier and shipped to one of the warehouses. However in most cases life is not as simple as that, when you are dealing with a large enterprise which is running operations in several countries or when you for example are working deploying at a company with a lot of locations in a single country you will have to think about how goods are purchased and distributed inside the company.

For a test I was asked to look into the following scenario which I tested on Oracle E-Business Suite Release 12 instance running the Vision demo environment. A company has multiple organizations defined in Oracle (for this example we use the Netherlands and Germany). In The Netherlands there are several regional warehouses defined in Oracle and in Germany (which is a separate organization in the instance) also a warehouse is defined. Only one warehouse is purchasing the item from a supplier.

Some warehouses are sourcing the goods from the warehouse which is sourcing from the supplier and others are sourcing again from them or from a sub-inventory in Germany. In this example we have only setup a single item to be handled like this. to setup the sourcing of a item per subinventory in Oracle E-Business suite your first query the item of the specified organization in the Item Master under the Oracle Inventory responsibility. When you have queried the item you go to "Tools" and "Item Subinventories".

In the above screenshot you can see that there are min-max quantities set, this however is not mandatory. For the purpose of the inventories always having enough stock available I set them so that min-max planning in Oracle e-Business suite will make sure that enough stock will be at every location.

However, the main interest of this test was setting the sourcing rules, as can seen in the below screenshot their is setup a way of distributing the item and making some subinventories source it from a other inventory or subinventory or a supplier site.

As can been seen subinventory "WH Amsterd" is sourcing from the supplier, this means that if the stock is dropping below the minimum min-max quantity it will purchase new goods from the supplier. Subinventories "WH Rotterd" and "WH Eindeho" will source it from the amsterdam warehouse. The warehouses "WH Meppel" and "WH Utrecht" will source from "WH Groning" which in his turn will get the goods from a different organization. As can seen the sourcing rules for "WH Groning" are set to source the goods from organization E1(which is Germany) and inventory (not subinventory) S1.

When you setup this in a correct way you can organize a entire sourcing model per item which can be very beneficial for your organization. However, if you want to do this correct and benefit from it you will have to plan it very carefully.

Saturday, May 09, 2009

In Python, as can been seen in some post I posted before this one, one can make use of tuples. A tuple is nothing more than a list. Wikipedia states the following on the subject of tuple:

In mathematics, a tuple is a sequence (or ordered list) of finite length. An n-tuple is a tuple with n elements. Tuples are usually written within parenthesis. For example, (2, 7, 4, 1, 7) is a 5-tuple. Tuples are often used to describe mathematical objects that consist of specified components. For example, a graph is commonly defined as the 2-tuple (V, E) where V is the set of vertices and E is the set of edges. The edge set E is a subset of the cartesian product V × V, hence a set of 2-tuples.

A tuple can widely be used within Python for all kinds of tasks, a first simple example is using a tuple to construct a sentence. The use of this example might not be clear at first for a day to day usage however it will illustrate the use of a tuple.In the above example we make use of a 2-tuple to construct the sentence. Now this example is not really useful in this setup because we could simply construct the entire sentence in one go and did not really have to make use of a tuple. However, in the below example you can see that if we define the content of a tuple first it already makes more sense.

Now we understand that we can define a tuple outside the print function as shown in the first example it suddenly will make a lot more sense. Even do we could still construct the above statement by using 2 string variables in this case the use of a tuple will make things more easy.

In the examples above we have used tuples to store strings, however in basic a tuple can hold any type of variable you need, so for example you can use it store also a int or a float. When you define a int or float inside a tuple it will also be in this variable type when you request it from the tuple. A example of this is below:

All of this is working just fine as long as you know the length of the tuple, in some cases you will encounter a situation where you do not know the length of your tuple, aka you do not know how many "items" it contains. in this case the len() command comes in handy. You can do a len(x) where x is the name of your tuple. This will return the number of "items" in your tuple. Remember, when accessing a tuple we start with "item" 0 and NOT 1. so if you need to get the last "item" from the tuple it will be n -1 where n is the number of items inside the tuple. You can see this in the example below:

In the last statement of the example above we do not a -1 on the len(x) in this case it is asking for unknowntup[7] which is not inside you tuple and this will result in the indexerror tuple index out of range.

We have already been discussing rounding of numbers in Python in a precious post, also I have been discussing the use of the math.ceil and math.floor functions that can be used in Python. However, there are some more places where rounding is done and that is when you use number formats when you print something.

for example we have the value 30.6475 which we would like to print to the screen as a dollar value like $30.65. What we could do is a rounding of the value 30.6475 and print it in combination with the dollar sign. It can also be done as shown below with a command like print "$%.02f" %30.6475

the 2f is used to define the amount of numbers behind the point. so we can make it for example 3 if we want a output like $30.648.

Wednesday, May 06, 2009

A couple of posts ago I have already been discussing the round function on Python which you can use to round your float variables. When discussing round we have to discuss the floor and ceil functions which are in the math library which ships with Python.

The functions floor and ceil are used to "round" a number to the nearest int value and still keep it as a float. For example floor will always "round" down to the nearest int value however will not make the float a int value. So if we floor 1.9 the result will be 1.0 and for ceil it will be the other way around. A example of ceil 1.2 will result in 2.0 and 2.1 will result in 3.0

To be able to use the floor and ceil functions you have to import the math class first by using the import command. A example is shown below with some example of math.floor(x) and math.ceil(x).

Tuesday, May 05, 2009

In the video below Oracle RAC or Oracle Real Application Cluster is explained in less than 3 minutes. It will not go over all the nice a good topics however in a very very short time you get the general idea. If you like the idea you can go into more detail on the Oracle website or even build your own Oracle RAC test environment in a virtual environment and play around.

Sunday, May 03, 2009

A couple of post ago I was talking about int and float variables and I showed how you can play with numbers and variables. When working with floating point variables one of the things you most likely will be doing at some point is rounding. when you have a float variable holding a value like 123.783635 you most likely do not want to present this in this form to the users, you most likely want to represent this like 123.78. In this case you will be needing the round function.

In this case we will be executing a command like round(123.783635, 2) because we like to have to numbers behind the digit. if we would like to have 1 number behind the digit we change the last number, something like; round(123.783635, 1).

This is quite easy and strait forward, however there are some more nice tricks you can do with the round function in Python. For example if we have the number 1259 and we like to round it to 1300 we can also use the round function by executing something like round(1259, -2). You can just play around with it some more to get a good idea on how it is working like in the example below.

Saturday, May 02, 2009

When defining items in Oracle E-Business Suite Release 12 (R12) and working on the setup of Oracle Inventory one of the things that you will have to look into is the Item Types. A item always needs to have a item type to identify what kind of item it is. By default Oracle will provide you a list of preset items which are already defined and which are used throughout the system. In basic the item types which are default in Oracle are usable and well thought about. The predefined Item Types are: ATO model, Finished good, Freight, Inventory Type, Kit, Model, Option Class, Outside processing item, PTO model, Phantom item,Planning, Product Family, Purchased item, Reference item, Subassembly and Supply item.

Even do those Item Types will cover for most of the items used in a general company it can be beneficial to setup your own Item Types. For example you might already have types defined for items which are commonly used in the company and the legacy systems of the company. For the adoption of a new system it can be good not to change this into new types or you might even have some dependencies on the Item Types towards other systems which makes that you have to define your own Item Types.

A Item Type for a Item is set when setting up the item in the Item Master, creating your own Item Types is done under a oracle Inventory responsibility where you are able to do setup. To create a new Item Type navigate to "Setup", "Items" and select "Item Types". Here you will be presented with a screen as shown below.

In the screenshot above you can see the definition of the Item Type Lookups. You can see that the lookups are defined for the application "Inventory" with the description "Item Types". Also you can see that by default the Item Types access level is set to User which indicates that users can add and change the lookups. That is, if they have access to the functionality via their responsibility.

What can and needs to be defined when creating a new Item Type;

Code: This is the unique identifier of the Item Type.Meaning: A free text field used to define the meaning of the Item Type.Description: A free text field used for providing a "human" description/identifier.Tag: tags can be used for the ease of maintenance, you can use it to group Item Types so you easily query and lookup groups of Item Types.Effective Dates: the from and to effective dates are used to define a time range when a Item Type becomes available for use and possible a date after which it no longer can be used. However it it not necessary to define this. If you do not provide a start date the Item Type will become affective immediately.Enabled: A checkbox where you can quickly activate or deactivate a Item Type when needed without making use of the effective dates.

Friday, May 01, 2009

When you start working and coding with python and this is your first experience with coding you will lost likely be puzzeld at first. Playing with numbers in coding can sometimes be somewhat strange because we can create different type of variables for numbers. manly you will be using FLOAT and INT values. where float numbers contain decimals int values will not.

some examples, lets first define some variables. We will create a variable A which will have the value 1 and we will create a variable B which will hold the value 2. When the are created we will divide A by B which by all common sense will give you 0.5 however as you can see in the example below it will give you 0 as the result instead of 0.5

The reason for this is that we have defined variables A and B as int values, we did not explicitly defined them as int however based upon the content of the variable it is defined as a int and a int value is not able to hold decimals. Because Python is now thinking we are working with only int values the answer is also a int value. We can define variables explicitly as a type of variable, for example if we wanted to have them represented as float values we define this with float(). Notice the example below.

Now the result will also be a float value and it will state 0.5 instead of 0. However if you do not want to define your variables explicitly as a float you can always "change" this when you do a operation on them. As you can see in the example below we have a variable a and b and they are int values as we can see at the outcome of dividing a by b. However now we do the same calculations and now we state that variable b is a float and the answer is suddenly a answer in float format. however, this is only limited to the operation as you can see because if we divide a by b again it is again a int value.

You can change the type of variable of variables a and b permanently, you can state that a = float(a) and then you will have them changed (until you change them to something else) You can see a example of it below.

Now you can come to a point that you are no longer sure what your variable is exactly, the type() function can help you with this. Just use the type() function in combination with your variable and you will be presented with the type of variable.