Variáveis, Tipos de Dados e Operadores

Variáveis e Memória

Uma variável em programação é uma referência ou um ponteiro para um espaço na memória do computador onde dados podem ser armazenados. Este espaço de memória contém valores que podem ser manipulados pelo programa. Quando criamos uma variável, estamos essencialmente etiquetando um pedaço da memória com um nome identificável.

Referência de Memória

Em linguagens de programação como Python, variáveis que armazenam tipos de dados imutáveis (como inteiros, floats e strings) apontam para um valor específico na memória. Se o valor da variável muda, na verdade, o que muda é para qual endereço de memória essa variável aponta, e não o valor no endereço de memória anterior.

Python – Referência de Memória



a = 5
b = a

print(f"a={a}")
print(f"b={b}")

a = 3

print(f"a={a}")
print(f"b={b}")


  

Aqui, a e b inicialmente apontam para o mesmo valor na memória (o valor 5). Quando mudamos a para 3, estamos mudando a para apontar para um novo valor na memória, mas b continua apontando para o valor original.

Compartilhamento de Endereço de Memória

Para tipos mutáveis, como listas, duas variáveis podem apontar para o mesmo objeto na memória. Alterações feitas através de uma variável são refletidas no objeto, afetando todas as variáveis que apontam para ele.

Python – Compartilhamento de Endereço de Memória



lista1 = [1, 2, 3]
lista2 = lista1
print("#lista1")
print(lista1)
print("")
print("#lista2")
print(lista2)

lista1.append(4)

print("#lista1")
print(lista1)
print("")
print("#lista2")
print(lista2)



  

lista1 e lista2 apontam para o mesmo objeto na memória. A modificação através de lista1 é visível em lista2.

Imutabilidade vs. Mutabilidade

Imutáveis: Tipos como int, float, str e tuple. Uma vez que um valor imutável é criado, ele não pode ser alterado. Qualquer “modificação” resulta em um novo objeto na memória.

Mutáveis: Tipos como list, dict, e objetos definidos pelo usuário. Eles podem ser alterados após a criação, o que significa que a alteração de seu conteúdo não cria um novo objeto na memória, mas sim modifica o objeto existente.

Python – Mutáveis vs Imutáveis



# Tipos imutáveis
num = 10       # int
print("id antes da alteração (imutável int):", id(num))
num += 1
print("id depois da alteração (imutável int):", id(num))

decimal = 10.5  # float
print("id antes da alteração (imutável float):", id(decimal))
decimal += 0.5
print("id depois da alteração (imutável float):", id(decimal))

texto = "Hello"  # str
print("id antes da alteração (imutável str):", id(texto))
texto += ", World!"
print("id depois da alteração (imutável str):", id(texto))

tup = (1, 2, 3)  # tuple
print("id antes da alteração (imutável tuple):", id(tup))
tup += (4,)
print("id depois da alteração (imutável tuple):", id(tup))

# Tipos mutáveis
lista = [1, 2, 3]  # list
print("id antes da alteração (mutável list):", id(lista))
lista.append(4)
print("id depois da alteração (mutável list):", id(lista))

dicionario = {'a': 1, 'b': 2}  # dict
print("id antes da alteração (mutável dict):", id(dicionario))
dicionario['c'] = 3
print("id depois da alteração (mutável dict):", id(dicionario))

# Exibindo as alterações
print("Valor final de num:", num)
print("Valor final de decimal:", decimal)
print("Valor final de texto:", texto)
print("Valor final de tup:", tup)
print("Valor final de lista:", lista)
print("Valor final de dicionario:", dicionario)

  

Neste exemplo, utilizamos a função id() para verificar a identidade do objeto na memória. Quando modificamos uma variável imutável, você observará que o ID do objeto (ou seja, seu endereço de memória) muda, pois um novo objeto é criado para representar o novo valor. Por outro lado, quando modificamos uma variável mutável, o ID permanece o mesmo, indicando que o mesmo objeto na memória foi alterado.

Tipos de Dados

Tipos de Dados Fundamentais

Inteiros (int): Representam números inteiros, positivos ou negativos, sem parte decimal. São imutáveis.

Ponto Flutuante (float): Representam números reais, contendo uma parte decimal. Também são imutáveis.

Strings (str): Sequências de caracteres usadas para armazenar texto. São imutáveis, o que significa que cada alteração em uma string resulta em um novo objeto string sendo criado.

Booleanos (bool): Possuem apenas dois valores: True ou False. Úteis para controle de fluxo e avaliação de condições.

Python – Tipos de Dados Na Prática



# Inteiros (int)
numero_inteiro = 42
print(type(numero_inteiro), numero_inteiro)

# Ponto Flutuante (float)
numero_flutuante = 3.14
print(type(numero_flutuante), numero_flutuante)

# Strings (str)
texto = "Olá, mundo!"
print(type(texto), texto)

# Alterando a string e mostrando que um novo objeto é criado
novo_texto = texto.upper()
print(type(novo_texto), novo_texto)
print("A string original é a mesma após a modificação?", texto is novo_texto)

# Booleanos (bool)
valor_verdadeiro = True
valor_falso = False
print(type(valor_verdadeiro), valor_verdadeiro)
print(type(valor_falso), valor_falso)

# Demonstração de como booleanos podem ser usados em uma condição
if valor_verdadeiro:
    print("Esta condição é verdadeira!")
else:
    print("Esta condição é falsa!")


  

Este código irá imprimir os tipos e valores das variáveis declaradas. Quando modificamos a string e criamos novo_texto, demonstramos que a string original não é alterada; em vez disso, um novo objeto string é criado. Isso ilustra a imutabilidade das strings. A verificação com o operador is mostra se o identificador (ou seja, a referência na memória) para texto e novo_texto é o mesmo, o que será falso, evidenciando que são objetos diferentes na memória. Por fim, os booleanos são usados em uma instrução condicional if, que é uma das principais utilizações desse tipo de dado.

Tipos de Dados Compostos:

Listas (list): Coleções ordenadas e mutáveis de itens. Podem conter itens de diferentes tipos.

Tuplas (tuple): Semelhantes às listas, mas imutáveis. Uma vez criadas, não podem ser alteradas.

Dicionários (dict): Coleções mutáveis de pares chave-valor. As chaves são únicas e imutáveis, enquanto os valores associados podem ser de qualquer tipo.

Python – Tipos Complexos



# Listas (list)
minha_lista = [1, "Python", 3.14, True]
print("Lista original:", minha_lista)

# Adicionando um elemento à lista
minha_lista.append("novo item")
print("Lista após adicionar um elemento:", minha_lista)

# Alterando um elemento da lista
minha_lista[0] = 2
print("Lista após alterar o primeiro elemento:", minha_lista)

# Iterando sobre os elementos da lista
for item in minha_lista:
    print(f"Item da lista: {item}")

# Tuplas (tuple)
minha_tupla = (1, "Python", 3.14, True)
print("\nTupla original:", minha_tupla)

# Tentativa de alterar um elemento da tupla (vai resultar em erro)
try:
    minha_tupla[0] = 2
except TypeError as e:
    print("Erro ao tentar alterar a tupla:", e)

# Iterando sobre os elementos da tupla
for item in minha_tupla:
    print(f"Item da tupla: {item}")

# Dicionários (dict)
meu_dicionario = {
    "int": 1,
    "str": "Python",
    "float": 3.14,
    "bool": True
}
print("\nDicionário original:", meu_dicionario)

# Adicionando um novo par chave-valor ao dicionário
meu_dicionario["novo"] = "item"
print("Dicionário após adicionar um novo par chave-valor:", meu_dicionario)

# Alterando o valor associado a uma chave
meu_dicionario["int"] = 2
print("Dicionário após alterar o valor da chave 'int':", meu_dicionario)

# Iterando sobre os pares chave-valor do dicionário
for chave, valor in meu_dicionario.items():
    print(f"Chave: {chave}, Valor: {valor}")

  

No exemplo acima:

Criamos uma lista com elementos de diferentes tipos e demonstramos como ela pode ser alterada e iterada.

Criamos uma tupla, também com elementos de tipos variados, e tentamos alterar um de seus elementos, o que gera um erro, pois tuplas são imutáveis.

Criamos um dicionário, que armazena pares chave-valor de tipos variados, e demonstramos como adicionar e modificar seus elementos, assim como iterar sobre eles.

O código inclui comentários explicativos para facilitar o entendimento de cada etapa. Ao executá-lo, você verá a saída correspondente a cada operação, ilustrando o comportamento mutável das listas e dicionários e a imutabilidade das tuplas.

Operadores

Operadores Aritméticos

Usados para realizar cálculos matemáticos comuns (+, -, *, /).

Divisão inteira (//) retorna o quociente da divisão, descartando a fração.

Módulo (%) retorna o resto da divisão.

Exponenciação (**) eleva um número pela potência de outro.

Operadores de Comparação

Comparam dois valores e retornam um booleano (True ou False).

Incluem igual (==), não igual (!=), maior que (>), menor que (<), maior ou igual (>=), menor ou igual (<=).

Operadores Lógicos

Usados para combinar expressões booleanas (and, or, not).

and retorna True se ambas as expressões forem verdadeiras.

or retorna True se pelo menos uma das expressões for verdadeira.

not inverte o valor booleano de uma expressão.

Python – Jogo de Operadores Aritméticos



import random
import operator

def gerar_expressao():
    operacoes = {
        '+': operator.add,
        '-': operator.sub,
        '*': operator.mul,
        '//': operator.floordiv,
        '%': operator.mod,
        '**': operator.pow
    }
    num1 = random.randint(1, 99)
    num2 = random.randint(1, 99) if random.choice(['%', '//']) else random.randint(1, 10)
    operacao = random.choice(list(operacoes.keys()))
    resposta_correta = operacoes[operacao](num1, num2)
    expressao = f"{num1} {operacao} {num2}"
    return expressao, resposta_correta

def verificar_resposta(resposta_jogador, resposta_correta):
    return resposta_jogador == resposta_correta

def jogar():
    jogadores = int(input("Quantos jogadores? (Máximo 4) "))
    pontuacoes = [0] * jogadores
    max_pontos = 5
    jogo_continua = True
    
    while jogo_continua:
        for j in range(jogadores):
            expressao, resposta_correta = gerar_expressao()
            print(f"Jogador {j + 1}, resolva: {expressao}")
            resposta_jogador = int(input("Sua resposta: "))
            
            if verificar_resposta(resposta_jogador, resposta_correta):
                print("Correto!")
                pontuacoes[j] += 1
                if pontuacoes[j] == max_pontos:
                    print(f"Jogador {j + 1} venceu o jogo com {max_pontos} pontos!")
                    jogo_continua = False
                    break
            else:
                print(f"Incorreto! A resposta correta era {resposta_correta}.")
    
    # Exibindo a pontuação final
    for j in range(jogadores):
        print(f"Jogador {j + 1} pontuação final: {pontuacoes[j]}")

# Começa o jogo
jogar()

  

Esse código inclui:

– Uma função gerar_expressao() que cria expressões matemáticas aleatórias e calcula a resposta.
– Uma função verificar_resposta() que compara a resposta do jogador com a resposta correta.
– Uma função jogar() que gerencia as rodadas do jogo, obtém respostas dos jogadores, atualiza as pontuações e exibe o resultado final.

Conclusão

Entender e aplicar corretamente os conceitos de variáveis, tipos de dados e operadores essencial para qualquer aspirante à desenvolvedor e nada melhor do que praticar com diversos exemplos e desafios que solidificarão seus entendimentos, desenvolverão habilidades em implementar códigos. E é por isto que você não pode perder o mais o seu precioso tempo, clique neste link agora para abrir o compilador, comece agora a executar seus códigos e assista a aula prática para acompanhar passo à passo a criação dos códigos.